New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

n3

Package Overview
Dependencies
Maintainers
1
Versions
127
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

n3 - npm Package Compare versions

Comparing version 1.1.1 to 1.2.0

.babelrc

36

lib/IRIs.js

@@ -1,30 +0,36 @@

var RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
XSD = 'http://www.w3.org/2001/XMLSchema#',
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
XSD = 'http://www.w3.org/2001/XMLSchema#',
SWAP = 'http://www.w3.org/2000/10/swap/';
module.exports = {
var _default = {
xsd: {
decimal: XSD + 'decimal',
boolean: XSD + 'boolean',
double: XSD + 'double',
double: XSD + 'double',
integer: XSD + 'integer',
string: XSD + 'string',
string: XSD + 'string'
},
rdf: {
type: RDF + 'type',
nil: RDF + 'nil',
first: RDF + 'first',
rest: RDF + 'rest',
langString: RDF + 'langString',
type: RDF + 'type',
nil: RDF + 'nil',
first: RDF + 'first',
rest: RDF + 'rest',
langString: RDF + 'langString'
},
owl: {
sameAs: 'http://www.w3.org/2002/07/owl#sameAs',
sameAs: 'http://www.w3.org/2002/07/owl#sameAs'
},
r: {
forSome: SWAP + 'reify#forSome',
forAll: SWAP + 'reify#forAll',
forAll: SWAP + 'reify#forAll'
},
log: {
implies: SWAP + 'log#implies',
},
implies: SWAP + 'log#implies'
}
};
exports.default = _default;

@@ -0,44 +1,51 @@

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _IRIs = _interopRequireDefault(require("./IRIs"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// N3.js implementations of the RDF/JS core data types
// See https://github.com/rdfjs/representation-task-force/blob/master/interface-spec.md
var namespaces = require('./IRIs');
var rdf = namespaces.rdf,
xsd = namespaces.xsd;
const {
rdf,
xsd
} = _IRIs.default;
var DataFactory, DEFAULTGRAPH;
var _blankNodeCounter = 0; // ## Term constructor
var _blankNodeCounter = 0;
class Term {
constructor(id) {
this.id = id;
}
} // ### The value of this term
// ### The value of this term
get value() {
return this.id;
}
} // ### Returns whether this object represents the same term as the other
// ### Returns whether this object represents the same term as the other
equals(other) {
// If both terms were created by this library,
// equality can be computed through ids
if (other instanceof Term)
return this.id === other.id;
// Otherwise, compare term type and value
return !!other && this.termType === other.termType &&
this.value === other.value;
}
if (other instanceof Term) return this.id === other.id; // Otherwise, compare term type and value
// ### Returns a plain object representation of this term
return !!other && this.termType === other.termType && this.value === other.value;
} // ### Returns a plain object representation of this term
toJSON() {
return {
termType: this.termType,
value: this.value,
value: this.value
};
}
}
} // ## NamedNode constructor
// ## NamedNode constructor
class NamedNode extends Term {

@@ -49,5 +56,6 @@ // ### The term type of this term

}
}
// ## Literal constructor
} // ## Literal constructor
class Literal extends Term {

@@ -57,44 +65,41 @@ // ### The term type of this term

return 'Literal';
}
} // ### The text value of this literal
// ### The text value of this literal
get value() {
return this.id.substring(1, this.id.lastIndexOf('"'));
}
} // ### The language of this literal
// ### The language of this literal
get language() {
// Find the last quotation mark (e.g., '"abc"@en-us')
var id = this.id, atPos = id.lastIndexOf('"') + 1;
// If "@" it follows, return the remaining substring; empty otherwise
var id = this.id,
atPos = id.lastIndexOf('"') + 1; // If "@" it follows, return the remaining substring; empty otherwise
return atPos < id.length && id[atPos++] === '@' ? id.substr(atPos).toLowerCase() : '';
}
} // ### The datatype IRI of this literal
// ### The datatype IRI of this literal
get datatype() {
return new NamedNode(this.datatypeString);
}
} // ### The datatype string of this literal
// ### The datatype string of this literal
get datatypeString() {
// Find the last quotation mark (e.g., '"abc"^^http://ex.org/types#t')
var id = this.id, dtPos = id.lastIndexOf('"') + 1, ch;
// If "^" it follows, return the remaining substring
return dtPos < id.length && (ch = id[dtPos]) === '^' ? id.substr(dtPos + 2) :
// If "@" follows, return rdf:langString; xsd:string otherwise
(ch !== '@' ? xsd.string : rdf.langString);
}
var id = this.id,
dtPos = id.lastIndexOf('"') + 1,
ch; // If "^" it follows, return the remaining substring
// ### Returns whether this object represents the same term as the other
return dtPos < id.length && (ch = id[dtPos]) === '^' ? id.substr(dtPos + 2) : // If "@" follows, return rdf:langString; xsd:string otherwise
ch !== '@' ? xsd.string : rdf.langString;
} // ### Returns whether this object represents the same term as the other
equals(other) {
// If both literals were created by this library,
// equality can be computed through ids
if (other instanceof Literal)
return this.id === other.id;
// Otherwise, compare term type, value, language, and datatype
return !!other && !!other.datatype &&
this.termType === other.termType &&
this.value === other.value &&
this.language === other.language &&
this.datatype.value === other.datatype.value;
if (other instanceof Literal) return this.id === other.id; // Otherwise, compare term type, value, language, and datatype
return !!other && !!other.datatype && this.termType === other.termType && this.value === other.value && this.language === other.language && this.datatype.value === other.datatype.value;
}

@@ -105,24 +110,29 @@

termType: this.termType,
value: this.value,
value: this.value,
language: this.language,
datatype: { termType: 'NamedNode', value: this.datatypeString },
datatype: {
termType: 'NamedNode',
value: this.datatypeString
}
};
}
}
// ## BlankNode constructor
} // ## BlankNode constructor
class BlankNode extends Term {
constructor(name) {
super('_:' + name);
}
} // ### The term type of this term
// ### The term type of this term
get termType() {
return 'BlankNode';
}
} // ### The name of this blank node
// ### The name of this blank node
get value() {
return this.id.substr(2);
}
}

@@ -133,16 +143,17 @@

super('?' + name);
}
} // ### The term type of this term
// ### The term type of this term
get termType() {
return 'Variable';
}
} // ### The name of this variable
// ### The name of this variable
get value() {
return this.id.substr(1);
}
}
// ## DefaultGraph constructor
} // ## DefaultGraph constructor
class DefaultGraph extends Term {

@@ -152,10 +163,10 @@ constructor() {

return DEFAULTGRAPH || this;
}
} // ### The term type of this term
// ### The term type of this term
get termType() {
return 'DefaultGraph';
}
} // ### Returns whether this object represents the same term as the other
// ### Returns whether this object represents the same term as the other
equals(other) {

@@ -165,176 +176,171 @@ // If both terms were created by this library,

// otherwise, compare term types.
return (this === other) || (!!other && (this.termType === other.termType));
return this === other || !!other && this.termType === other.termType;
}
}
// ## DefaultGraph singleton
DEFAULTGRAPH = new DefaultGraph();
} // ## DefaultGraph singleton
// ### Constructs a term from the given internal string ID
DEFAULTGRAPH = new DefaultGraph(); // ### Constructs a term from the given internal string ID
function fromId(id, factory) {
factory = factory || DataFactory;
factory = factory || DataFactory; // Falsy value or empty string indicate the default graph
// Falsy value or empty string indicate the default graph
if (!id)
return factory.defaultGraph();
if (!id) return factory.defaultGraph(); // Identify the term type based on the first character
// Identify the term type based on the first character
switch (id[0]) {
case '_': return factory.blankNode(id.substr(2));
case '?': return factory.variable(id.substr(1));
case '"':
// Shortcut for internal literals
if (factory === DataFactory)
return new Literal(id);
// Literal without datatype or language
if (id[id.length - 1] === '"')
return factory.literal(id.substr(1, id.length - 2));
// Literal with datatype or language
var endPos = id.lastIndexOf('"', id.length - 1);
return factory.literal(id.substr(1, endPos - 1),
id[endPos + 1] === '@' ? id.substr(endPos + 2)
: factory.namedNode(id.substr(endPos + 3)));
default: return factory.namedNode(id);
case '_':
return factory.blankNode(id.substr(2));
case '?':
return factory.variable(id.substr(1));
case '"':
// Shortcut for internal literals
if (factory === DataFactory) return new Literal(id); // Literal without datatype or language
if (id[id.length - 1] === '"') return factory.literal(id.substr(1, id.length - 2)); // Literal with datatype or language
var endPos = id.lastIndexOf('"', id.length - 1);
return factory.literal(id.substr(1, endPos - 1), id[endPos + 1] === '@' ? id.substr(endPos + 2) : factory.namedNode(id.substr(endPos + 3)));
default:
return factory.namedNode(id);
}
}
} // ### Constructs an internal string ID from the given term or ID string
// ### Constructs an internal string ID from the given term or ID string
function toId(term) {
if (typeof term === 'string')
return term;
if (term instanceof Term)
return term.id;
if (!term)
return DEFAULTGRAPH.id;
if (typeof term === 'string') return term;
if (term instanceof Term) return term.id;
if (!term) return DEFAULTGRAPH.id; // Term instantiated with another library
// Term instantiated with another library
switch (term.termType) {
case 'NamedNode': return term.value;
case 'BlankNode': return '_:' + term.value;
case 'Variable': return '?' + term.value;
case 'DefaultGraph': return '';
case 'Literal': return '"' + term.value + '"' +
(term.language ? '@' + term.language :
(term.datatype && term.datatype.value !== xsd.string ? '^^' + term.datatype.value : ''));
default: throw new Error('Unexpected termType: ' + term.termType);
case 'NamedNode':
return term.value;
case 'BlankNode':
return '_:' + term.value;
case 'Variable':
return '?' + term.value;
case 'DefaultGraph':
return '';
case 'Literal':
return '"' + term.value + '"' + (term.language ? '@' + term.language : term.datatype && term.datatype.value !== xsd.string ? '^^' + term.datatype.value : '');
default:
throw new Error('Unexpected termType: ' + term.termType);
}
}
} // ## Quad constructor
// ## Quad constructor
class Quad {
constructor(subject, predicate, object, graph) {
this.subject = subject;
this.subject = subject;
this.predicate = predicate;
this.object = object;
this.graph = graph || DEFAULTGRAPH;
}
this.object = object;
this.graph = graph || DEFAULTGRAPH;
} // ### Returns a plain object representation of this quad
// ### Returns a plain object representation of this quad
toJSON() {
return {
subject: this.subject.toJSON(),
subject: this.subject.toJSON(),
predicate: this.predicate.toJSON(),
object: this.object.toJSON(),
graph: this.graph.toJSON(),
object: this.object.toJSON(),
graph: this.graph.toJSON()
};
}
} // ### Returns whether this object represents the same quad as the other
// ### Returns whether this object represents the same quad as the other
equals(other) {
return !!other && this.subject.equals(other.subject) &&
this.predicate.equals(other.predicate) &&
this.object.equals(other.object) &&
this.graph.equals(other.graph);
return !!other && this.subject.equals(other.subject) && this.predicate.equals(other.predicate) && this.object.equals(other.object) && this.graph.equals(other.graph);
}
}
} // ## DataFactory singleton
// ## DataFactory functions
// ### Creates an IRI
DataFactory = {
// ### Public factory functions
namedNode,
blankNode,
variable,
literal,
defaultGraph,
quad,
triple: quad,
// ### Internal datatype constructors
internal: {
Term,
NamedNode,
BlankNode,
Variable,
Literal,
DefaultGraph,
Quad,
Triple: Quad,
fromId,
toId
}
};
var _default = DataFactory; // ### Creates an IRI
exports.default = _default;
function namedNode(iri) {
return new NamedNode(iri);
}
} // ### Creates a blank node
// ### Creates a blank node
function blankNode(name) {
if (!name)
name = 'n3-' + _blankNodeCounter++;
if (!name) name = 'n3-' + _blankNodeCounter++;
return new BlankNode(name);
}
} // ### Creates a literal
// ### Creates a literal
function literal(value, languageOrDataType) {
// Create a language-tagged string
if (typeof languageOrDataType === 'string')
return new Literal('"' + value + '"@' + languageOrDataType.toLowerCase());
if (typeof languageOrDataType === 'string') return new Literal('"' + value + '"@' + languageOrDataType.toLowerCase()); // Create a datatyped literal
// Create a datatyped literal
var datatype = languageOrDataType && languageOrDataType.value || '';
if (!datatype) {
switch (typeof value) {
// Convert a boolean
case 'boolean':
datatype = xsd.boolean;
break;
// Convert an integer or double
case 'number':
if (Number.isFinite(value))
datatype = Number.isInteger(value) ? xsd.integer : xsd.double;
else {
datatype = xsd.double;
if (!Number.isNaN(value))
value = value > 0 ? 'INF' : '-INF';
}
break;
// No datatype, so convert a plain string
default:
return new Literal('"' + value + '"');
// Convert a boolean
case 'boolean':
datatype = xsd.boolean;
break;
// Convert an integer or double
case 'number':
if (Number.isFinite(value)) datatype = Number.isInteger(value) ? xsd.integer : xsd.double;else {
datatype = xsd.double;
if (!Number.isNaN(value)) value = value > 0 ? 'INF' : '-INF';
}
break;
// No datatype, so convert a plain string
default:
return new Literal('"' + value + '"');
}
}
return new Literal('"' + value + '"^^' + datatype);
}
} // ### Creates a variable
// ### Creates a variable
function variable(name) {
return new Variable(name);
}
} // ### Returns the default graph
// ### Returns the default graph
function defaultGraph() {
return DEFAULTGRAPH;
}
} // ### Creates a quad
// ### Creates a quad
function quad(subject, predicate, object, graph) {
return new Quad(subject, predicate, object, graph);
}
// ## Module exports
module.exports = DataFactory = {
// ### Public factory functions
namedNode: namedNode,
blankNode: blankNode,
variable: variable,
literal: literal,
defaultGraph: defaultGraph,
quad: quad,
triple: quad,
// ### Internal datatype constructors
internal: {
Term: Term,
NamedNode: NamedNode,
BlankNode: BlankNode,
Variable: Variable,
Literal: Literal,
DefaultGraph: DefaultGraph,
Quad: Quad,
Triple: Quad,
fromId: fromId,
toId: toId,
},
};
}

@@ -1,20 +0,52 @@

// **N3Lexer** tokenizes N3 documents.
var xsd = require('./IRIs').xsd;
"use strict";
var fromCharCode = String.fromCharCode;
var immediately = typeof setImmediate === 'function' ? setImmediate :
function setImmediate(func) { setTimeout(func, 0); };
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
// Regular expression and replacement string to escape N3 strings.
var _IRIs = _interopRequireDefault(require("./IRIs"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// **N3Lexer** tokenizes N3 documents.
const {
xsd
} = _IRIs.default;
const {
fromCharCode
} = String; // Regular expression and replacement string to escape N3 strings.
// Note how we catch invalid unicode sequences separately (they will trigger an error).
var escapeSequence = /\\u([a-fA-F0-9]{4})|\\U([a-fA-F0-9]{8})|\\[uU]|\\(.)/g;
var escapeReplacements = {
'\\': '\\', "'": "'", '"': '"',
'n': '\n', 'r': '\r', 't': '\t', 'f': '\f', 'b': '\b',
'_': '_', '~': '~', '.': '.', '-': '-', '!': '!', '$': '$', '&': '&',
'(': '(', ')': ')', '*': '*', '+': '+', ',': ',', ';': ';', '=': '=',
'/': '/', '?': '?', '#': '#', '@': '@', '%': '%',
'\\': '\\',
"'": "'",
'"': '"',
'n': '\n',
'r': '\r',
't': '\t',
'f': '\f',
'b': '\b',
'_': '_',
'~': '~',
'.': '.',
'-': '-',
'!': '!',
'$': '$',
'&': '&',
'(': '(',
')': ')',
'*': '*',
'+': '+',
',': ',',
';': ';',
'=': '=',
'/': '/',
'?': '?',
'#': '#',
'@': '@',
'%': '%'
};
var illegalIriChars = /[\x00-\x20<>\\"\{\}\|\^\`]/;
var lineModeRegExps = {

@@ -30,7 +62,6 @@ _iri: true,

_whitespace: true,
_endOfFile: true,
_endOfFile: true
};
var invalidRegExp = /$0^/;
var invalidRegExp = /$0^/; // ## Constructor
// ## Constructor
class N3Lexer {

@@ -41,9 +72,12 @@ constructor(options) {

this._iri = /^<((?:[^ <>{}\\]|\\[uU])+)>[ \t]*/; // IRI with escape sequences; needs sanity check after unescaping
this._unescapedIri = /^<([^\x00-\x20<>\\"\{\}\|\^\`]*)>[ \t]*/; // IRI without escape sequences; no unescaping
this._unescapedQuote = /^"([^"\\\r\n]+)"/; // non-empty string without escape sequences
this._unescapedApos = /^'([^'\\\r\n]+)'/;
this._unescapedApos = /^'([^'\\\r\n]+)'/;
this._singleQuote = /^"((?:[^"\\\r\n]|\\.)*)"(?=[^"])/;
this._singleApos = /^'((?:[^'\\\r\n]|\\.)*)'(?=[^'])/;
this._singleApos = /^'((?:[^'\\\r\n]|\\.)*)'(?=[^'])/;
this._tripleQuote = /^"""([^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*)"""/;
this._tripleApos = /^'''([^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*)'''/;
this._tripleApos = /^'''([^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*)'''/;
this._langcode = /^@([a-z]+(?:-[a-z0-9]+)*)(?=[^a-z0-9\-])/i;

@@ -63,43 +97,46 @@ this._prefix = /^((?:[A-Za-z\xc0-\xd6\xd8-\xf6\xf8-\u02ff\u0370-\u037d\u037f-\u1fff\u200c\u200d\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff])(?:\.?[\-0-9A-Z_a-z\xb7\xc0-\xd6\xd8-\xf6\xf8-\u037d\u037f-\u1fff\u200c\u200d\u203f\u2040\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff\uf900-\ufdcf\ufdf0-\ufffd]|[\ud800-\udb7f][\udc00-\udfff])*)?:(?=[#\s<])/;

this._endOfFile = /^(?:#[^\n\r]*)?$/;
options = options || {};
options = options || {}; // In line mode (N-Triples or N-Quads), only simple features may be parsed
// In line mode (N-Triples or N-Quads), only simple features may be parsed
if (this._lineMode = !!options.lineMode) {
this._n3Mode = false;
// Don't tokenize special literals
this._n3Mode = false; // Don't tokenize special literals
for (var key in this) {
if (!(key in lineModeRegExps) && this[key] instanceof RegExp)
this[key] = invalidRegExp;
if (!(key in lineModeRegExps) && this[key] instanceof RegExp) this[key] = invalidRegExp;
}
}
// When not in line mode, enable N3 functionality by default
} // When not in line mode, enable N3 functionality by default
else {
this._n3Mode = options.n3 !== false;
}
// Don't output comment tokens by default
this._n3Mode = options.n3 !== false;
} // Don't output comment tokens by default
this._comments = !!options.comments;
}
} // ## Private methods
// ### `_tokenizeToEnd` tokenizes as for as possible, emitting tokens through the callback
// ## Private methods
// ### `_tokenizeToEnd` tokenizes as for as possible, emitting tokens through the callback
_tokenizeToEnd(callback, inputFinished) {
// Continue parsing as far as possible; the loop will return eventually
var input = this._input, outputComments = this._comments;
var input = this._input,
outputComments = this._comments;
while (true) {
// Count and skip whitespace lines
var whiteSpaceMatch, comment;
while (whiteSpaceMatch = this._newline.exec(input)) {
// Try to find a comment
if (outputComments && (comment = this._comment.exec(whiteSpaceMatch[0])))
callback(null, { line: this._line, type: 'comment', value: comment[1], prefix: '' });
// Advance the input
if (outputComments && (comment = this._comment.exec(whiteSpaceMatch[0]))) callback(null, {
line: this._line,
type: 'comment',
value: comment[1],
prefix: ''
}); // Advance the input
input = input.substr(whiteSpaceMatch[0].length, input.length);
this._line++;
}
// Skip whitespace on current line
if (whiteSpaceMatch = this._whitespace.exec(input))
input = input.substr(whiteSpaceMatch[0].length, input.length);
} // Skip whitespace on current line
// Stop for now if we're at the end
if (whiteSpaceMatch = this._whitespace.exec(input)) input = input.substr(whiteSpaceMatch[0].length, input.length); // Stop for now if we're at the end
if (this._endOfFile.test(input)) {

@@ -109,240 +146,226 @@ // If the input is finished, emit EOF

// Try to find a final comment
if (outputComments && (comment = this._comment.exec(input)))
callback(null, { line: this._line, type: 'comment', value: comment[1], prefix: '' });
callback(input = null, { line: this._line, type: 'eof', value: '', prefix: '' });
if (outputComments && (comment = this._comment.exec(input))) callback(null, {
line: this._line,
type: 'comment',
value: comment[1],
prefix: ''
});
callback(input = null, {
line: this._line,
type: 'eof',
value: '',
prefix: ''
});
}
return this._input = input;
}
} // Look for specific token types based on the first character
// Look for specific token types based on the first character
var line = this._line, type = '', value = '', prefix = '',
firstChar = input[0], match = null, matchLength = 0, inconclusive = false;
var line = this._line,
type = '',
value = '',
prefix = '',
firstChar = input[0],
match = null,
matchLength = 0,
inconclusive = false;
switch (firstChar) {
case '^':
// We need at least 3 tokens lookahead to distinguish ^^<IRI> and ^^pre:fixed
if (input.length < 3)
case '^':
// We need at least 3 tokens lookahead to distinguish ^^<IRI> and ^^pre:fixed
if (input.length < 3) break; // Try to match a type
else if (input[1] === '^') {
this._previousMarker = '^^'; // Move to type IRI or prefixed name
input = input.substr(2);
if (input[0] !== '<') {
inconclusive = true;
break;
}
} // If no type, it must be a path expression
else {
if (this._n3Mode) {
matchLength = 1;
type = '^';
}
break;
}
// Fall through in case the type is an IRI
case '<':
// Try to find a full IRI without escape sequences
if (match = this._unescapedIri.exec(input)) type = 'IRI', value = match[1]; // Try to find a full IRI with escape sequences
else if (match = this._iri.exec(input)) {
value = this._unescape(match[1]);
if (value === null || illegalIriChars.test(value)) return reportSyntaxError(this);
type = 'IRI';
} // Try to find a backwards implication arrow
else if (this._n3Mode && input.length > 1 && input[1] === '=') type = 'inverse', matchLength = 2, value = '>';
break;
// Try to match a type
else if (input[1] === '^') {
this._previousMarker = '^^';
// Move to type IRI or prefixed name
input = input.substr(2);
if (input[0] !== '<') {
inconclusive = true;
break;
}
}
// If no type, it must be a path expression
else {
if (this._n3Mode) {
matchLength = 1;
type = '^';
}
case '_':
// Try to find a blank node. Since it can contain (but not end with) a dot,
// we always need a non-dot character before deciding it is a blank node.
// Therefore, try inserting a space if we're at the end of the input.
if ((match = this._blank.exec(input)) || inputFinished && (match = this._blank.exec(input + ' '))) type = 'blank', prefix = '_', value = match[1];
break;
}
// Fall through in case the type is an IRI
case '<':
// Try to find a full IRI without escape sequences
if (match = this._unescapedIri.exec(input))
type = 'IRI', value = match[1];
// Try to find a full IRI with escape sequences
else if (match = this._iri.exec(input)) {
value = this._unescape(match[1]);
if (value === null || illegalIriChars.test(value))
return reportSyntaxError(this);
type = 'IRI';
}
// Try to find a backwards implication arrow
else if (this._n3Mode && input.length > 1 && input[1] === '=')
type = 'inverse', matchLength = 2, value = '>';
break;
case '_':
// Try to find a blank node. Since it can contain (but not end with) a dot,
// we always need a non-dot character before deciding it is a blank node.
// Therefore, try inserting a space if we're at the end of the input.
if ((match = this._blank.exec(input)) ||
inputFinished && (match = this._blank.exec(input + ' ')))
type = 'blank', prefix = '_', value = match[1];
break;
case '"':
// Try to find a literal without escape sequences
if (match = this._unescapedQuote.exec(input)) value = match[1]; // Before attempting more complex string patterns, try to detect a closing quote
else if (input.indexOf('"', 1) > 0) {
// Try to find any other literal wrapped in a pair of quotes
if (match = this._singleQuote.exec(input)) value = this._unescape(match[1]); // Try to find a literal wrapped in three pairs of quotes
else if (match = this._tripleQuote.exec(input)) {
value = match[1]; // Advance line counter
case '"':
// Try to find a literal without escape sequences
if (match = this._unescapedQuote.exec(input))
value = match[1];
// Before attempting more complex string patterns, try to detect a closing quote
else if (input.indexOf('"', 1) > 0) {
// Try to find any other literal wrapped in a pair of quotes
if (match = this._singleQuote.exec(input))
value = this._unescape(match[1]);
// Try to find a literal wrapped in three pairs of quotes
else if (match = this._tripleQuote.exec(input)) {
value = match[1];
// Advance line counter
this._line += value.split(/\r\n|\r|\n/).length - 1;
value = this._unescape(value);
this._line += value.split(/\r\n|\r|\n/).length - 1;
value = this._unescape(value);
}
if (value === null) return reportSyntaxError(this);
}
if (match !== null) type = 'literal';
break;
case "'":
// Try to find a literal without escape sequences
if (match = this._unescapedApos.exec(input)) value = match[1]; // Before attempting more complex string patterns, try to detect a closing apostrophe
else if (input.indexOf("'", 1) > 0) {
// Try to find any other literal wrapped in a pair of apostrophes
if (match = this._singleApos.exec(input)) value = this._unescape(match[1]); // Try to find a literal wrapped in three pairs of apostrophes
else if (match = this._tripleApos.exec(input)) {
value = match[1]; // Advance line counter
this._line += value.split(/\r\n|\r|\n/).length - 1;
value = this._unescape(value);
}
if (value === null) return reportSyntaxError(this);
}
if (match !== null) type = 'literal';
break;
case '?':
// Try to find a variable
if (this._n3Mode && (match = this._variable.exec(input))) type = 'var', value = match[0];
break;
case '@':
// Try to find a language code
if (this._previousMarker === 'literal' && (match = this._langcode.exec(input))) type = 'langcode', value = match[1]; // Try to find a keyword
else if (match = this._keyword.exec(input)) type = match[0];
break;
case '.':
// Try to find a dot as punctuation
if (input.length === 1 ? inputFinished : input[1] < '0' || input[1] > '9') {
type = '.';
matchLength = 1;
break;
}
if (value === null)
return reportSyntaxError(this);
}
if (match !== null)
type = 'literal';
break;
case "'":
// Try to find a literal without escape sequences
if (match = this._unescapedApos.exec(input))
value = match[1];
// Before attempting more complex string patterns, try to detect a closing apostrophe
else if (input.indexOf("'", 1) > 0) {
// Try to find any other literal wrapped in a pair of apostrophes
if (match = this._singleApos.exec(input))
value = this._unescape(match[1]);
// Try to find a literal wrapped in three pairs of apostrophes
else if (match = this._tripleApos.exec(input)) {
value = match[1];
// Advance line counter
this._line += value.split(/\r\n|\r|\n/).length - 1;
value = this._unescape(value);
// Fall through to numerical case (could be a decimal dot)
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '+':
case '-':
// Try to find a number. Since it can contain (but not end with) a dot,
// we always need a non-dot character before deciding it is a number.
// Therefore, try inserting a space if we're at the end of the input.
if (match = this._number.exec(input) || inputFinished && (match = this._number.exec(input + ' '))) {
type = 'literal', value = match[0];
prefix = match[1] ? xsd.double : /^[+\-]?\d+$/.test(match[0]) ? xsd.integer : xsd.decimal;
}
if (value === null)
return reportSyntaxError(this);
}
if (match !== null)
type = 'literal';
break;
case '?':
// Try to find a variable
if (this._n3Mode && (match = this._variable.exec(input)))
type = 'var', value = match[0];
break;
break;
case '@':
// Try to find a language code
if (this._previousMarker === 'literal' && (match = this._langcode.exec(input)))
type = 'langcode', value = match[1];
// Try to find a keyword
else if (match = this._keyword.exec(input))
type = match[0];
break;
case 'B':
case 'b':
case 'p':
case 'P':
case 'G':
case 'g':
// Try to find a SPARQL-style keyword
if (match = this._sparqlKeyword.exec(input)) type = match[0].toUpperCase();else inconclusive = true;
break;
case '.':
// Try to find a dot as punctuation
if (input.length === 1 ? inputFinished : (input[1] < '0' || input[1] > '9')) {
type = '.';
matchLength = 1;
case 'f':
case 't':
// Try to match a boolean
if (match = this._boolean.exec(input)) type = 'literal', value = match[0], prefix = xsd.boolean;else inconclusive = true;
break;
}
// Fall through to numerical case (could be a decimal dot)
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '+':
case '-':
// Try to find a number. Since it can contain (but not end with) a dot,
// we always need a non-dot character before deciding it is a number.
// Therefore, try inserting a space if we're at the end of the input.
if (match = this._number.exec(input) ||
inputFinished && (match = this._number.exec(input + ' '))) {
type = 'literal', value = match[0];
prefix = (match[1] ? xsd.double :
(/^[+\-]?\d+$/.test(match[0]) ? xsd.integer : xsd.decimal));
}
break;
case 'a':
// Try to find an abbreviated predicate
if (match = this._shortPredicates.exec(input)) type = 'abbreviation', value = 'a';else inconclusive = true;
break;
case 'B':
case 'b':
case 'p':
case 'P':
case 'G':
case 'g':
// Try to find a SPARQL-style keyword
if (match = this._sparqlKeyword.exec(input))
type = match[0].toUpperCase();
else
inconclusive = true;
break;
case '=':
// Try to find an implication arrow or equals sign
if (this._n3Mode && input.length > 1) {
type = 'abbreviation';
if (input[1] !== '>') matchLength = 1, value = '=';else matchLength = 2, value = '>';
}
case 'f':
case 't':
// Try to match a boolean
if (match = this._boolean.exec(input))
type = 'literal', value = match[0], prefix = xsd.boolean;
else
inconclusive = true;
break;
break;
case 'a':
// Try to find an abbreviated predicate
if (match = this._shortPredicates.exec(input))
type = 'abbreviation', value = 'a';
else
inconclusive = true;
break;
case '!':
if (!this._n3Mode) break;
case '=':
// Try to find an implication arrow or equals sign
if (this._n3Mode && input.length > 1) {
type = 'abbreviation';
if (input[1] !== '>')
matchLength = 1, value = '=';
else
matchLength = 2, value = '>';
}
break;
case ',':
case ';':
case '[':
case ']':
case '(':
case ')':
case '{':
case '}':
if (!this._lineMode) {
matchLength = 1;
type = firstChar;
}
case '!':
if (!this._n3Mode)
break;
case ',':
case ';':
case '[':
case ']':
case '(':
case ')':
case '{':
case '}':
if (!this._lineMode) {
matchLength = 1;
type = firstChar;
}
break;
default:
inconclusive = true;
}
default:
inconclusive = true;
} // Some first characters do not allow an immediate decision, so inspect more
// Some first characters do not allow an immediate decision, so inspect more
if (inconclusive) {
// Try to find a prefix
if ((this._previousMarker === '@prefix' || this._previousMarker === 'PREFIX') &&
(match = this._prefix.exec(input)))
type = 'prefix', value = match[1] || '';
// Try to find a prefixed name. Since it can contain (but not end with) a dot,
if ((this._previousMarker === '@prefix' || this._previousMarker === 'PREFIX') && (match = this._prefix.exec(input))) type = 'prefix', value = match[1] || ''; // Try to find a prefixed name. Since it can contain (but not end with) a dot,
// we always need a non-dot character before deciding it is a prefixed name.
// Therefore, try inserting a space if we're at the end of the input.
else if ((match = this._prefixed.exec(input)) ||
inputFinished && (match = this._prefixed.exec(input + ' ')))
type = 'prefixed', prefix = match[1] || '', value = this._unescape(match[2]);
}
else if ((match = this._prefixed.exec(input)) || inputFinished && (match = this._prefixed.exec(input + ' '))) type = 'prefixed', prefix = match[1] || '', value = this._unescape(match[2]);
} // A type token is special: it can only be emitted after an IRI or prefixed name is read
// A type token is special: it can only be emitted after an IRI or prefixed name is read
if (this._previousMarker === '^^') {
switch (type) {
case 'prefixed': type = 'type'; break;
case 'IRI': type = 'typeIRI'; break;
default: type = '';
case 'prefixed':
type = 'type';
break;
case 'IRI':
type = 'typeIRI';
break;
default:
type = '';
}
}
} // What if nothing of the above was found?
// What if nothing of the above was found?
if (!type) {

@@ -352,22 +375,26 @@ // We could be in streaming mode, and then we just wait for more input to arrive.

// One exception: error on an unaccounted linebreak (= not inside a triple-quoted literal).
if (inputFinished || (!/^'''|^"""/.test(input) && /\n|\r/.test(input)))
return reportSyntaxError(this);
else
return this._input = input;
}
if (inputFinished || !/^'''|^"""/.test(input) && /\n|\r/.test(input)) return reportSyntaxError(this);else return this._input = input;
} // Emit the parsed token
// Emit the parsed token
var token = { line: line, type: type, value: value, prefix: prefix };
var token = {
line: line,
type: type,
value: value,
prefix: prefix
};
callback(null, token);
this.previousToken = token;
this._previousMarker = type;
// Advance to next part to tokenize
this._previousMarker = type; // Advance to next part to tokenize
input = input.substr(matchLength || match[0].length, input.length);
} // Signals the syntax error through the callback
function reportSyntaxError(self) {
callback(self._syntaxError(/^\S*/.exec(input)[0]));
}
} // ### `_unescape` replaces N3 escape codes by their corresponding characters
// Signals the syntax error through the callback
function reportSyntaxError(self) { callback(self._syntaxError(/^\S*/.exec(input)[0])); }
}
// ### `_unescape` replaces N3 escape codes by their corresponding characters
_unescape(item) {

@@ -377,25 +404,26 @@ try {

var charCode;
if (unicode4) {
charCode = parseInt(unicode4, 16);
if (isNaN(charCode)) throw new Error(); // can never happen (regex), but helps performance
return fromCharCode(charCode);
}
else if (unicode8) {
} else if (unicode8) {
charCode = parseInt(unicode8, 16);
if (isNaN(charCode)) throw new Error(); // can never happen (regex), but helps performance
if (charCode <= 0xFFFF) return fromCharCode(charCode);
return fromCharCode(0xD800 + ((charCode -= 0x10000) / 0x400), 0xDC00 + (charCode & 0x3FF));
}
else {
return fromCharCode(0xD800 + (charCode -= 0x10000) / 0x400, 0xDC00 + (charCode & 0x3FF));
} else {
var replacement = escapeReplacements[escapedChar];
if (!replacement)
throw new Error();
if (!replacement) throw new Error();
return replacement;
}
});
} catch (error) {
return null;
}
catch (error) { return null; }
}
} // ### `_syntaxError` creates a syntax error for the given issue
// ### `_syntaxError` creates a syntax error for the given issue
_syntaxError(issue) {

@@ -407,66 +435,66 @@ this._input = null;

line: this._line,
previousToken: this.previousToken,
previousToken: this.previousToken
};
return err;
}
} // ## Public methods
// ### `tokenize` starts the transformation of an N3 document into an array of tokens.
// The input can be a string or a stream.
// ## Public methods
// ### `tokenize` starts the transformation of an N3 document into an array of tokens.
// The input can be a string or a stream.
tokenize(input, callback) {
var self = this;
this._line = 1;
this._line = 1; // If the input is a string, continuously emit tokens through the callback until the end
// If the input is a string, continuously emit tokens through the callback until the end
if (typeof input === 'string') {
this._input = input;
// If a callback was passed, asynchronously call it
if (typeof callback === 'function')
immediately(function () { self._tokenizeToEnd(callback, true); });
// If no callback was passed, tokenize synchronously and return
this._input = input; // If a callback was passed, asynchronously call it
if (typeof callback === 'function') setImmediate(function () {
self._tokenizeToEnd(callback, true);
}); // If no callback was passed, tokenize synchronously and return
else {
var tokens = [], error;
this._tokenizeToEnd(function (e, t) { e ? (error = e) : tokens.push(t); }, true);
if (error) throw error;
return tokens;
}
}
// Otherwise, the input must be a stream
var tokens = [],
error;
this._tokenizeToEnd(function (e, t) {
e ? error = e : tokens.push(t);
}, true);
if (error) throw error;
return tokens;
}
} // Otherwise, the input must be a stream
else {
this._input = '';
this._pendingBuffer = null;
if (typeof input.setEncoding === 'function')
input.setEncoding('utf8');
// Adds the data chunk to the buffer and parses as far as possible
input.on('data', function (data) {
if (self._input !== null && data.length !== 0) {
// Prepend any previous pending writes
if (self._pendingBuffer) {
data = Buffer.concat([self._pendingBuffer, data]);
self._pendingBuffer = null;
this._input = '';
this._pendingBuffer = null;
if (typeof input.setEncoding === 'function') input.setEncoding('utf8'); // Adds the data chunk to the buffer and parses as far as possible
input.on('data', function (data) {
if (self._input !== null && data.length !== 0) {
// Prepend any previous pending writes
if (self._pendingBuffer) {
data = Buffer.concat([self._pendingBuffer, data]);
self._pendingBuffer = null;
} // Hold if the buffer ends in an incomplete unicode sequence
if (data[data.length - 1] & 0x80) {
self._pendingBuffer = data;
} // Otherwise, tokenize as far as possible
else {
self._input += data;
self._tokenizeToEnd(callback, false);
}
}
// Hold if the buffer ends in an incomplete unicode sequence
if (data[data.length - 1] & 0x80) {
self._pendingBuffer = data;
}
// Otherwise, tokenize as far as possible
else {
self._input += data;
self._tokenizeToEnd(callback, false);
}
}
});
// Parses until the end
input.on('end', function () {
if (self._input !== null)
self._tokenizeToEnd(callback, true);
});
input.on('error', callback);
}
}); // Parses until the end
input.on('end', function () {
if (self._input !== null) self._tokenizeToEnd(callback, true);
});
input.on('error', callback);
}
}
}
// ## Exports
module.exports = N3Lexer;
exports.default = N3Lexer;

@@ -0,105 +1,120 @@

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _N3Lexer = _interopRequireDefault(require("./N3Lexer"));
var _N3DataFactory = _interopRequireDefault(require("./N3DataFactory"));
var _IRIs = _interopRequireDefault(require("./IRIs"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// **N3Parser** parses N3 documents.
var Lexer = require('./N3Lexer'),
DataFactory = require('./N3DataFactory'),
namespaces = require('./IRIs');
// The next ID for new blank nodes
var blankNodePrefix = 0, blankNodeCount = 0;
var blankNodePrefix = 0,
blankNodeCount = 0; // ## Constructor
// ## Constructor
class N3Parser {
constructor(options) {
this._contextStack = [];
this._graph = null;
this._graph = null; // Set the document IRI
// Set the document IRI
options = options || {};
this._setBase(options.baseIRI);
options.factory && initDataFactory(this, options.factory);
// Set supported features depending on the format
var format = (typeof options.format === 'string') ?
options.format.match(/\w*$/)[0].toLowerCase() : '',
isTurtle = format === 'turtle', isTriG = format === 'trig',
isNTriples = /triple/.test(format), isNQuads = /quad/.test(format),
options.factory && initDataFactory(this, options.factory); // Set supported features depending on the format
var format = typeof options.format === 'string' ? options.format.match(/\w*$/)[0].toLowerCase() : '',
isTurtle = format === 'turtle',
isTriG = format === 'trig',
isNTriples = /triple/.test(format),
isNQuads = /quad/.test(format),
isN3 = this._n3Mode = /n3/.test(format),
isLineMode = isNTriples || isNQuads;
if (!(this._supportsNamedGraphs = !(isTurtle || isN3)))
this._readPredicateOrNamedGraph = this._readPredicate;
this._supportsQuads = !(isTurtle || isTriG || isNTriples || isN3);
// Disable relative IRIs in N-Triples or N-Quads mode
if (isLineMode)
this._resolveRelativeIRI = function (iri) { return ''; };
this._blankNodePrefix = typeof options.blankNodePrefix !== 'string' ? '' :
options.blankNodePrefix.replace(/^(?!_:)/, '_:');
this._lexer = options.lexer || new Lexer({ lineMode: isLineMode, n3: isN3 });
// Disable explicit quantifiers by default
if (!(this._supportsNamedGraphs = !(isTurtle || isN3))) this._readPredicateOrNamedGraph = this._readPredicate;
this._supportsQuads = !(isTurtle || isTriG || isNTriples || isN3); // Disable relative IRIs in N-Triples or N-Quads mode
if (isLineMode) this._resolveRelativeIRI = function (iri) {
return '';
};
this._blankNodePrefix = typeof options.blankNodePrefix !== 'string' ? '' : options.blankNodePrefix.replace(/^(?!_:)/, '_:');
this._lexer = options.lexer || new _N3Lexer.default({
lineMode: isLineMode,
n3: isN3
}); // Disable explicit quantifiers by default
this._explicitQuantifiers = !!options.explicitQuantifiers;
}
} // ## Static class methods
// ### `_resetBlankNodeIds` restarts blank node identification
// ## Static class methods
// ### `_resetBlankNodeIds` restarts blank node identification
static _resetBlankNodeIds() {
blankNodePrefix = blankNodeCount = 0;
}
} // ## Private methods
// ### `_blank` creates a new blank node
// ## Private methods
// ### `_blank` creates a new blank node
_blank() {
return this._blankNode('b' + blankNodeCount++);
}
} // ### `_setBase` sets the base IRI to resolve relative IRIs
// ### `_setBase` sets the base IRI to resolve relative IRIs
_setBase(baseIRI) {
if (!baseIRI)
this._base = null;
else {
if (!baseIRI) this._base = null;else {
// Remove fragment if present
var fragmentPos = baseIRI.indexOf('#');
if (fragmentPos >= 0)
baseIRI = baseIRI.substr(0, fragmentPos);
// Set base IRI and its components
if (fragmentPos >= 0) baseIRI = baseIRI.substr(0, fragmentPos); // Set base IRI and its components
this._base = baseIRI;
this._basePath = baseIRI.indexOf('/') < 0 ? baseIRI :
baseIRI.replace(/[^\/?]*(?:\?.*)?$/, '');
this._basePath = baseIRI.indexOf('/') < 0 ? baseIRI : baseIRI.replace(/[^\/?]*(?:\?.*)?$/, '');
baseIRI = baseIRI.match(/^(?:([a-z][a-z0-9+.-]*:))?(?:\/\/[^\/]*)?/i);
this._baseRoot = baseIRI[0];
this._baseRoot = baseIRI[0];
this._baseScheme = baseIRI[1];
}
}
} // ### `_saveContext` stores the current parsing context
// when entering a new scope (list, blank node, formula)
// ### `_saveContext` stores the current parsing context
// when entering a new scope (list, blank node, formula)
_saveContext(type, graph, subject, predicate, object) {
var n3Mode = this._n3Mode;
this._contextStack.push({
subject: subject, predicate: predicate, object: object,
graph: graph, type: type,
subject: subject,
predicate: predicate,
object: object,
graph: graph,
type: type,
inverse: n3Mode ? this._inversePredicate : false,
blankPrefix: n3Mode ? this._prefixes._ : '',
quantified: n3Mode ? this._quantified : null,
});
// The settings below only apply to N3 streams
quantified: n3Mode ? this._quantified : null
}); // The settings below only apply to N3 streams
if (n3Mode) {
// Every new scope resets the predicate direction
this._inversePredicate = false;
// In N3, blank nodes are scoped to a formula
this._inversePredicate = false; // In N3, blank nodes are scoped to a formula
// (using a dot as separator, as a blank node label cannot start with it)
this._prefixes._ = (this._graph ? this._graph.id.substr(2) + '.' : '.');
// Quantifiers are scoped to a formula
this._prefixes._ = this._graph ? this._graph.id.substr(2) + '.' : '.'; // Quantifiers are scoped to a formula
this._quantified = Object.create(this._quantified);
}
}
} // ### `_restoreContext` restores the parent context
// when leaving a scope (list, blank node, formula)
// ### `_restoreContext` restores the parent context
// when leaving a scope (list, blank node, formula)
_restoreContext() {
var context = this._contextStack.pop(), n3Mode = this._n3Mode;
this._subject = context.subject;
var context = this._contextStack.pop(),
n3Mode = this._n3Mode;
this._subject = context.subject;
this._predicate = context.predicate;
this._object = context.object;
this._graph = context.graph;
// The settings below only apply to N3 streams
this._object = context.object;
this._graph = context.graph; // The settings below only apply to N3 streams
if (n3Mode) {

@@ -110,217 +125,235 @@ this._inversePredicate = context.inverse;

}
}
} // ### `_readInTopContext` reads a token when in the top context
// ### `_readInTopContext` reads a token when in the top context
_readInTopContext(token) {
switch (token.type) {
// If an EOF token arrives in the top context, signal that we're done
case 'eof':
if (this._graph !== null)
return this._error('Unclosed graph', token);
delete this._prefixes._;
return this._callback(null, null, this._prefixes);
// It could be a prefix declaration
case 'PREFIX':
this._sparqlStyle = true;
case '@prefix':
return this._readPrefix;
// It could be a base declaration
case 'BASE':
this._sparqlStyle = true;
case '@base':
return this._readBaseIRI;
// It could be a graph
case '{':
if (this._supportsNamedGraphs) {
this._graph = '';
this._subject = null;
return this._readSubject;
}
case 'GRAPH':
if (this._supportsNamedGraphs)
return this._readNamedGraphLabel;
// Otherwise, the next token must be a subject
default:
return this._readSubject(token);
// If an EOF token arrives in the top context, signal that we're done
case 'eof':
if (this._graph !== null) return this._error('Unclosed graph', token);
delete this._prefixes._;
return this._callback(null, null, this._prefixes);
// It could be a prefix declaration
case 'PREFIX':
this._sparqlStyle = true;
case '@prefix':
return this._readPrefix;
// It could be a base declaration
case 'BASE':
this._sparqlStyle = true;
case '@base':
return this._readBaseIRI;
// It could be a graph
case '{':
if (this._supportsNamedGraphs) {
this._graph = '';
this._subject = null;
return this._readSubject;
}
case 'GRAPH':
if (this._supportsNamedGraphs) return this._readNamedGraphLabel;
// Otherwise, the next token must be a subject
default:
return this._readSubject(token);
}
}
} // ### `_readEntity` reads an IRI, prefixed name, blank node, or variable
// ### `_readEntity` reads an IRI, prefixed name, blank node, or variable
_readEntity(token, quantifier) {
var value;
switch (token.type) {
// Read a relative or absolute IRI
case 'IRI':
case 'typeIRI':
var iri = this._resolveIRI(token.value);
if (iri === '')
return this._error('Invalid IRI', token);
value = this._namedNode(iri);
break;
// Read a prefixed name
case 'type':
case 'prefixed':
var prefix = this._prefixes[token.prefix];
if (prefix === undefined)
return this._error('Undefined prefix "' + token.prefix + ':"', token);
value = this._namedNode(prefix + token.value);
break;
// Read a blank node
case 'blank':
value = this._blankNode(this._prefixes[token.prefix] + token.value);
break;
// Read a variable
case 'var':
value = this._variable(token.value.substr(1));
break;
// Everything else is not an entity
default:
return this._error('Expected entity but got ' + token.type, token);
}
// In N3 mode, replace the entity if it is quantified
if (!quantifier && this._n3Mode && (value.id in this._quantified))
value = this._quantified[value.id];
// Read a relative or absolute IRI
case 'IRI':
case 'typeIRI':
var iri = this._resolveIRI(token.value);
if (iri === '') return this._error('Invalid IRI', token);
value = this._namedNode(iri);
break;
// Read a prefixed name
case 'type':
case 'prefixed':
var prefix = this._prefixes[token.prefix];
if (prefix === undefined) return this._error('Undefined prefix "' + token.prefix + ':"', token);
value = this._namedNode(prefix + token.value);
break;
// Read a blank node
case 'blank':
value = this._blankNode(this._prefixes[token.prefix] + token.value);
break;
// Read a variable
case 'var':
value = this._variable(token.value.substr(1));
break;
// Everything else is not an entity
default:
return this._error('Expected entity but got ' + token.type, token);
} // In N3 mode, replace the entity if it is quantified
if (!quantifier && this._n3Mode && value.id in this._quantified) value = this._quantified[value.id];
return value;
}
} // ### `_readSubject` reads a quad's subject
// ### `_readSubject` reads a quad's subject
_readSubject(token) {
this._predicate = null;
switch (token.type) {
case '[':
// Start a new quad with a new blank node as subject
this._saveContext('blank', this._graph,
this._subject = this._blank(), null, null);
return this._readBlankNodeHead;
case '(':
// Start a new list
this._saveContext('list', this._graph, this.RDF_NIL, null, null);
this._subject = null;
return this._readListItem;
case '{':
// Start a new formula
if (!this._n3Mode)
return this._error('Unexpected graph', token);
this._saveContext('formula', this._graph,
this._graph = this._blank(), null, null);
return this._readSubject;
case '}':
// No subject; the graph in which we are reading is closed instead
return this._readPunctuation(token);
case '@forSome':
if (!this._n3Mode)
return this._error('Unexpected "@forSome"', token);
this._subject = null;
this._predicate = this.N3_FORSOME;
this._quantifier = this._blankNode;
return this._readQuantifierList;
case '@forAll':
if (!this._n3Mode)
return this._error('Unexpected "@forAll"', token);
this._subject = null;
this._predicate = this.N3_FORALL;
this._quantifier = this._variable;
return this._readQuantifierList;
default:
// Read the subject entity
if ((this._subject = this._readEntity(token)) === undefined)
return;
// In N3 mode, the subject might be a path
if (this._n3Mode)
return this._getPathReader(this._readPredicateOrNamedGraph);
}
case '[':
// Start a new quad with a new blank node as subject
this._saveContext('blank', this._graph, this._subject = this._blank(), null, null);
// The next token must be a predicate,
return this._readBlankNodeHead;
case '(':
// Start a new list
this._saveContext('list', this._graph, this.RDF_NIL, null, null);
this._subject = null;
return this._readListItem;
case '{':
// Start a new formula
if (!this._n3Mode) return this._error('Unexpected graph', token);
this._saveContext('formula', this._graph, this._graph = this._blank(), null, null);
return this._readSubject;
case '}':
// No subject; the graph in which we are reading is closed instead
return this._readPunctuation(token);
case '@forSome':
if (!this._n3Mode) return this._error('Unexpected "@forSome"', token);
this._subject = null;
this._predicate = this.N3_FORSOME;
this._quantifier = this._blankNode;
return this._readQuantifierList;
case '@forAll':
if (!this._n3Mode) return this._error('Unexpected "@forAll"', token);
this._subject = null;
this._predicate = this.N3_FORALL;
this._quantifier = this._variable;
return this._readQuantifierList;
default:
// Read the subject entity
if ((this._subject = this._readEntity(token)) === undefined) return; // In N3 mode, the subject might be a path
if (this._n3Mode) return this._getPathReader(this._readPredicateOrNamedGraph);
} // The next token must be a predicate,
// or, if the subject was actually a graph IRI, a named graph
return this._readPredicateOrNamedGraph;
}
} // ### `_readPredicate` reads a quad's predicate
// ### `_readPredicate` reads a quad's predicate
_readPredicate(token) {
var type = token.type;
switch (type) {
case 'inverse':
this._inversePredicate = true;
case 'abbreviation':
this._predicate = this.ABBREVIATIONS[token.value];
break;
case '.':
case ']':
case '}':
// Expected predicate didn't come, must have been trailing semicolon
if (this._predicate === null)
return this._error('Unexpected ' + type, token);
this._subject = null;
return type === ']' ? this._readBlankNodeTail(token) : this._readPunctuation(token);
case ';':
// Additional semicolons can be safely ignored
return this._predicate !== null ? this._readPredicate :
this._error('Expected predicate but got ;', token);
case 'blank':
if (!this._n3Mode)
return this._error('Disallowed blank node as predicate', token);
default:
if ((this._predicate = this._readEntity(token)) === undefined)
return;
}
// The next token must be an object
case 'inverse':
this._inversePredicate = true;
case 'abbreviation':
this._predicate = this.ABBREVIATIONS[token.value];
break;
case '.':
case ']':
case '}':
// Expected predicate didn't come, must have been trailing semicolon
if (this._predicate === null) return this._error('Unexpected ' + type, token);
this._subject = null;
return type === ']' ? this._readBlankNodeTail(token) : this._readPunctuation(token);
case ';':
// Additional semicolons can be safely ignored
return this._predicate !== null ? this._readPredicate : this._error('Expected predicate but got ;', token);
case 'blank':
if (!this._n3Mode) return this._error('Disallowed blank node as predicate', token);
default:
if ((this._predicate = this._readEntity(token)) === undefined) return;
} // The next token must be an object
return this._readObject;
}
} // ### `_readObject` reads a quad's object
// ### `_readObject` reads a quad's object
_readObject(token) {
switch (token.type) {
case 'literal':
// Regular literal, can still get a datatype or language
if (token.prefix.length === 0) {
this._literalValue = token.value;
return this._readDataTypeOrLang;
}
// Pre-datatyped string literal (prefix stores the datatype)
else
this._object = this._literal(token.value, this._namedNode(token.prefix));
break;
case '[':
// Start a new quad with a new blank node as subject
this._saveContext('blank', this._graph, this._subject, this._predicate,
this._subject = this._blank());
return this._readBlankNodeHead;
case '(':
// Start a new list
this._saveContext('list', this._graph, this._subject, this._predicate, this.RDF_NIL);
this._subject = null;
return this._readListItem;
case '{':
// Start a new formula
if (!this._n3Mode)
return this._error('Unexpected graph', token);
this._saveContext('formula', this._graph, this._subject, this._predicate,
this._graph = this._blank());
return this._readSubject;
default:
// Read the object entity
if ((this._object = this._readEntity(token)) === undefined)
return;
// In N3 mode, the object might be a path
if (this._n3Mode)
return this._getPathReader(this._getContextEndReader());
case 'literal':
// Regular literal, can still get a datatype or language
if (token.prefix.length === 0) {
this._literalValue = token.value;
return this._readDataTypeOrLang;
} // Pre-datatyped string literal (prefix stores the datatype)
else this._object = this._literal(token.value, this._namedNode(token.prefix));
break;
case '[':
// Start a new quad with a new blank node as subject
this._saveContext('blank', this._graph, this._subject, this._predicate, this._subject = this._blank());
return this._readBlankNodeHead;
case '(':
// Start a new list
this._saveContext('list', this._graph, this._subject, this._predicate, this.RDF_NIL);
this._subject = null;
return this._readListItem;
case '{':
// Start a new formula
if (!this._n3Mode) return this._error('Unexpected graph', token);
this._saveContext('formula', this._graph, this._subject, this._predicate, this._graph = this._blank());
return this._readSubject;
default:
// Read the object entity
if ((this._object = this._readEntity(token)) === undefined) return; // In N3 mode, the object might be a path
if (this._n3Mode) return this._getPathReader(this._getContextEndReader());
}
return this._getContextEndReader();
}
} // ### `_readPredicateOrNamedGraph` reads a quad's predicate, or a named graph
// ### `_readPredicateOrNamedGraph` reads a quad's predicate, or a named graph
_readPredicateOrNamedGraph(token) {
return token.type === '{' ? this._readGraph(token) : this._readPredicate(token);
}
} // ### `_readGraph` reads a graph
// ### `_readGraph` reads a graph
_readGraph(token) {
if (token.type !== '{')
return this._error('Expected graph but got ' + token.type, token);
// The "subject" we read is actually the GRAPH's label
if (token.type !== '{') return this._error('Expected graph but got ' + token.type, token); // The "subject" we read is actually the GRAPH's label
this._graph = this._subject, this._subject = null;
return this._readSubject;
}
} // ### `_readBlankNodeHead` reads the head of a blank node
// ### `_readBlankNodeHead` reads the head of a blank node
_readBlankNodeHead(token) {

@@ -330,125 +363,120 @@ if (token.type === ']') {

return this._readBlankNodeTail(token);
}
else {
} else {
this._predicate = null;
return this._readPredicate(token);
}
}
} // ### `_readBlankNodeTail` reads the end of a blank node
// ### `_readBlankNodeTail` reads the end of a blank node
_readBlankNodeTail(token) {
if (token.type !== ']')
return this._readBlankNodePunctuation(token);
if (token.type !== ']') return this._readBlankNodePunctuation(token); // Store blank node quad
// Store blank node quad
if (this._subject !== null)
this._emit(this._subject, this._predicate, this._object, this._graph);
if (this._subject !== null) this._emit(this._subject, this._predicate, this._object, this._graph); // Restore the parent context containing this blank node
// Restore the parent context containing this blank node
var empty = this._predicate === null;
this._restoreContext();
// If the blank node was the subject, continue reading the predicate
if (this._object === null)
// If the blank node was empty, it could be a named graph label
return empty ? this._readPredicateOrNamedGraph : this._readPredicateAfterBlank;
// If the blank node was the object, restore previous context and read punctuation
else
return this._getContextEndReader();
}
// ### `_readPredicateAfterBlank` reads a predicate after an anonymous blank node
this._restoreContext(); // If the blank node was the subject, continue reading the predicate
if (this._object === null) // If the blank node was empty, it could be a named graph label
return empty ? this._readPredicateOrNamedGraph : this._readPredicateAfterBlank; // If the blank node was the object, restore previous context and read punctuation
else return this._getContextEndReader();
} // ### `_readPredicateAfterBlank` reads a predicate after an anonymous blank node
_readPredicateAfterBlank(token) {
switch (token.type) {
case '.':
case '}':
// No predicate is coming if the triple is terminated here
this._subject = null;
return this._readPunctuation(token);
default:
return this._readPredicate(token);
case '.':
case '}':
// No predicate is coming if the triple is terminated here
this._subject = null;
return this._readPunctuation(token);
default:
return this._readPredicate(token);
}
}
} // ### `_readListItem` reads items from a list
// ### `_readListItem` reads items from a list
_readListItem(token) {
var item = null, // The item of the list
list = null, // The list itself
previousList = this._subject, // The previous list that contains this list
stack = this._contextStack, // The stack of parent contexts
parent = stack[stack.length - 1], // The parent containing the current list
next = this._readListItem; // The next function to execute
var item = null,
// The item of the list
list = null,
// The list itself
previousList = this._subject,
// The previous list that contains this list
stack = this._contextStack,
// The stack of parent contexts
parent = stack[stack.length - 1],
// The parent containing the current list
next = this._readListItem; // The next function to execute
switch (token.type) {
case '[':
// Stack the current list quad and start a new quad with a blank node as subject
this._saveContext('blank', this._graph,
list = this._blank(), this.RDF_FIRST,
this._subject = item = this._blank());
next = this._readBlankNodeHead;
break;
case '(':
// Stack the current list quad and start a new list
this._saveContext('list', this._graph,
list = this._blank(), this.RDF_FIRST, this.RDF_NIL);
this._subject = null;
break;
case ')':
// Closing the list; restore the parent context
this._restoreContext();
// If this list is contained within a parent list, return the membership quad here.
// This will be `<parent list element> rdf:first <this list>.`.
if (stack.length !== 0 && stack[stack.length - 1].type === 'list')
this._emit(this._subject, this._predicate, this._object, this._graph);
// Was this list the parent's subject?
if (this._predicate === null) {
// The next token is the predicate
next = this._readPredicate;
// No list tail if this was an empty list
if (this._subject === this.RDF_NIL)
return next;
}
// The list was in the parent context's object
else {
next = this._getContextEndReader();
// No list tail if this was an empty list
if (this._object === this.RDF_NIL)
return next;
}
// Close the list by making the head nil
list = this.RDF_NIL;
break;
case 'literal':
// Regular literal, can still get a datatype or language
if (token.prefix.length === 0) {
this._literalValue = token.value;
next = this._readListItemDataTypeOrLang;
}
// Pre-datatyped string literal (prefix stores the datatype)
else {
item = this._literal(token.value, this._namedNode(token.prefix));
next = this._getContextEndReader();
}
break;
default:
if ((item = this._readEntity(token)) === undefined)
return;
}
case '[':
// Stack the current list quad and start a new quad with a blank node as subject
this._saveContext('blank', this._graph, list = this._blank(), this.RDF_FIRST, this._subject = item = this._blank());
// Create a new blank node if no item head was assigned yet
if (list === null)
this._subject = list = this._blank();
next = this._readBlankNodeHead;
break;
// Is this the first element of the list?
case '(':
// Stack the current list quad and start a new list
this._saveContext('list', this._graph, list = this._blank(), this.RDF_FIRST, this.RDF_NIL);
this._subject = null;
break;
case ')':
// Closing the list; restore the parent context
this._restoreContext(); // If this list is contained within a parent list, return the membership quad here.
// This will be `<parent list element> rdf:first <this list>.`.
if (stack.length !== 0 && stack[stack.length - 1].type === 'list') this._emit(this._subject, this._predicate, this._object, this._graph); // Was this list the parent's subject?
if (this._predicate === null) {
// The next token is the predicate
next = this._readPredicate; // No list tail if this was an empty list
if (this._subject === this.RDF_NIL) return next;
} // The list was in the parent context's object
else {
next = this._getContextEndReader(); // No list tail if this was an empty list
if (this._object === this.RDF_NIL) return next;
} // Close the list by making the head nil
list = this.RDF_NIL;
break;
case 'literal':
// Regular literal, can still get a datatype or language
if (token.prefix.length === 0) {
this._literalValue = token.value;
next = this._readListItemDataTypeOrLang;
} // Pre-datatyped string literal (prefix stores the datatype)
else {
item = this._literal(token.value, this._namedNode(token.prefix));
next = this._getContextEndReader();
}
break;
default:
if ((item = this._readEntity(token)) === undefined) return;
} // Create a new blank node if no item head was assigned yet
if (list === null) this._subject = list = this._blank(); // Is this the first element of the list?
if (previousList === null) {
// This list is either the subject or the object of its parent
if (parent.predicate === null)
parent.subject = list;
else
parent.object = list;
}
else {
if (parent.predicate === null) parent.subject = list;else parent.object = list;
} else {
// Continue the previous list with the current list
this._emit(previousList, this.RDF_REST, list, this._graph);
}
// If an item was read, add it to the list
} // If an item was read, add it to the list
if (item !== null) {

@@ -459,194 +487,211 @@ // In N3 mode, the item might be a path

this._saveContext('item', this._graph, list, this.RDF_FIRST, item);
this._subject = item, this._predicate = null;
// _readPath will restore the context and output the item
this._subject = item, this._predicate = null; // _readPath will restore the context and output the item
return this._getPathReader(this._readListItem);
}
// Output the item
} // Output the item
this._emit(list, this.RDF_FIRST, item, this._graph);
}
return next;
}
} // ### `_readDataTypeOrLang` reads an _optional_ datatype or language
// ### `_readDataTypeOrLang` reads an _optional_ datatype or language
_readDataTypeOrLang(token) {
return this._completeLiteral(token, false);
}
} // ### `_readListItemDataTypeOrLang` reads an _optional_ datatype or language in a list
// ### `_readListItemDataTypeOrLang` reads an _optional_ datatype or language in a list
_readListItemDataTypeOrLang(token) {
return this._completeLiteral(token, true);
}
} // ### `_completeLiteral` completes a literal with an optional datatype or language
// ### `_completeLiteral` completes a literal with an optional datatype or language
_completeLiteral(token, listItem) {
switch (token.type) {
// Create a datatyped literal
case 'type':
case 'typeIRI':
var datatype = this._readEntity(token);
if (datatype === undefined) return; // No datatype means an error occurred
this._object = this._literal(this._literalValue, datatype);
token = null;
break;
// Create a language-tagged string
case 'langcode':
this._object = this._literal(this._literalValue, token.value);
token = null;
break;
// Create a simple string literal
default:
this._object = this._literal(this._literalValue);
}
// If this literal was part of a list, write the item
// Create a datatyped literal
case 'type':
case 'typeIRI':
var datatype = this._readEntity(token);
if (datatype === undefined) return; // No datatype means an error occurred
this._object = this._literal(this._literalValue, datatype);
token = null;
break;
// Create a language-tagged string
case 'langcode':
this._object = this._literal(this._literalValue, token.value);
token = null;
break;
// Create a simple string literal
default:
this._object = this._literal(this._literalValue);
} // If this literal was part of a list, write the item
// (we could also check the context stack, but passing in a flag is faster)
if (listItem)
this._emit(this._subject, this.RDF_FIRST, this._object, this._graph);
// If the token was consumed, continue with the rest of the input
if (token === null)
return this._getContextEndReader();
// Otherwise, consume the token now
if (listItem) this._emit(this._subject, this.RDF_FIRST, this._object, this._graph); // If the token was consumed, continue with the rest of the input
if (token === null) return this._getContextEndReader(); // Otherwise, consume the token now
else {
this._readCallback = this._getContextEndReader();
return this._readCallback(token);
}
}
this._readCallback = this._getContextEndReader();
return this._readCallback(token);
}
} // ### `_readFormulaTail` reads the end of a formula
// ### `_readFormulaTail` reads the end of a formula
_readFormulaTail(token) {
if (token.type !== '}')
return this._readPunctuation(token);
if (token.type !== '}') return this._readPunctuation(token); // Store the last quad of the formula
// Store the last quad of the formula
if (this._subject !== null)
this._emit(this._subject, this._predicate, this._object, this._graph);
if (this._subject !== null) this._emit(this._subject, this._predicate, this._object, this._graph); // Restore the parent context containing this formula
// Restore the parent context containing this formula
this._restoreContext();
// If the formula was the subject, continue reading the predicate.
this._restoreContext(); // If the formula was the subject, continue reading the predicate.
// If the formula was the object, read punctuation.
return this._object === null ? this._readPredicate : this._getContextEndReader();
}
} // ### `_readPunctuation` reads punctuation between quads or quad parts
// ### `_readPunctuation` reads punctuation between quads or quad parts
_readPunctuation(token) {
var next, subject = this._subject, graph = this._graph,
var next,
subject = this._subject,
graph = this._graph,
inversePredicate = this._inversePredicate;
switch (token.type) {
// A closing brace ends a graph
case '}':
if (this._graph === null)
return this._error('Unexpected graph closing', token);
if (this._n3Mode)
return this._readFormulaTail(token);
this._graph = null;
// A dot just ends the statement, without sharing anything with the next
case '.':
this._subject = null;
next = this._contextStack.length ? this._readSubject : this._readInTopContext;
if (inversePredicate) this._inversePredicate = false;
break;
// Semicolon means the subject is shared; predicate and object are different
case ';':
next = this._readPredicate;
break;
// Comma means both the subject and predicate are shared; the object is different
case ',':
next = this._readObject;
break;
default:
// An entity means this is a quad (only allowed if not already inside a graph)
if (this._supportsQuads && this._graph === null && (graph = this._readEntity(token)) !== undefined) {
next = this._readQuadPunctuation;
// A closing brace ends a graph
case '}':
if (this._graph === null) return this._error('Unexpected graph closing', token);
if (this._n3Mode) return this._readFormulaTail(token);
this._graph = null;
// A dot just ends the statement, without sharing anything with the next
case '.':
this._subject = null;
next = this._contextStack.length ? this._readSubject : this._readInTopContext;
if (inversePredicate) this._inversePredicate = false;
break;
}
return this._error('Expected punctuation to follow "' + this._object.id + '"', token);
}
// A quad has been completed now, so return it
// Semicolon means the subject is shared; predicate and object are different
case ';':
next = this._readPredicate;
break;
// Comma means both the subject and predicate are shared; the object is different
case ',':
next = this._readObject;
break;
default:
// An entity means this is a quad (only allowed if not already inside a graph)
if (this._supportsQuads && this._graph === null && (graph = this._readEntity(token)) !== undefined) {
next = this._readQuadPunctuation;
break;
}
return this._error('Expected punctuation to follow "' + this._object.id + '"', token);
} // A quad has been completed now, so return it
if (subject !== null) {
var predicate = this._predicate, object = this._object;
if (!inversePredicate)
this._emit(subject, predicate, object, graph);
else
this._emit(object, predicate, subject, graph);
var predicate = this._predicate,
object = this._object;
if (!inversePredicate) this._emit(subject, predicate, object, graph);else this._emit(object, predicate, subject, graph);
}
return next;
}
} // ### `_readBlankNodePunctuation` reads punctuation in a blank node
// ### `_readBlankNodePunctuation` reads punctuation in a blank node
_readBlankNodePunctuation(token) {
var next;
switch (token.type) {
// Semicolon means the subject is shared; predicate and object are different
case ';':
next = this._readPredicate;
break;
// Comma means both the subject and predicate are shared; the object is different
case ',':
next = this._readObject;
break;
default:
return this._error('Expected punctuation to follow "' + this._object.id + '"', token);
}
// A quad has been completed now, so return it
// Semicolon means the subject is shared; predicate and object are different
case ';':
next = this._readPredicate;
break;
// Comma means both the subject and predicate are shared; the object is different
case ',':
next = this._readObject;
break;
default:
return this._error('Expected punctuation to follow "' + this._object.id + '"', token);
} // A quad has been completed now, so return it
this._emit(this._subject, this._predicate, this._object, this._graph);
return next;
}
} // ### `_readQuadPunctuation` reads punctuation after a quad
// ### `_readQuadPunctuation` reads punctuation after a quad
_readQuadPunctuation(token) {
if (token.type !== '.')
return this._error('Expected dot to follow quad', token);
if (token.type !== '.') return this._error('Expected dot to follow quad', token);
return this._readInTopContext;
}
} // ### `_readPrefix` reads the prefix of a prefix declaration
// ### `_readPrefix` reads the prefix of a prefix declaration
_readPrefix(token) {
if (token.type !== 'prefix')
return this._error('Expected prefix to follow @prefix', token);
if (token.type !== 'prefix') return this._error('Expected prefix to follow @prefix', token);
this._prefix = token.value;
return this._readPrefixIRI;
}
} // ### `_readPrefixIRI` reads the IRI of a prefix declaration
// ### `_readPrefixIRI` reads the IRI of a prefix declaration
_readPrefixIRI(token) {
if (token.type !== 'IRI')
return this._error('Expected IRI to follow prefix "' + this._prefix + ':"', token);
if (token.type !== 'IRI') return this._error('Expected IRI to follow prefix "' + this._prefix + ':"', token);
var prefixNode = this._readEntity(token);
this._prefixes[this._prefix] = prefixNode.value;
this._prefixCallback(this._prefix, prefixNode);
return this._readDeclarationPunctuation;
}
} // ### `_readBaseIRI` reads the IRI of a base declaration
// ### `_readBaseIRI` reads the IRI of a base declaration
_readBaseIRI(token) {
var iri = token.type === 'IRI' && this._resolveIRI(token.value);
if (!iri)
return this._error('Expected valid IRI to follow base declaration', token);
if (!iri) return this._error('Expected valid IRI to follow base declaration', token);
this._setBase(iri);
return this._readDeclarationPunctuation;
}
} // ### `_readNamedGraphLabel` reads the label of a named graph
// ### `_readNamedGraphLabel` reads the label of a named graph
_readNamedGraphLabel(token) {
switch (token.type) {
case 'IRI':
case 'blank':
case 'prefixed':
return this._readSubject(token), this._readGraph;
case '[':
return this._readNamedGraphBlankLabel;
default:
return this._error('Invalid graph label', token);
case 'IRI':
case 'blank':
case 'prefixed':
return this._readSubject(token), this._readGraph;
case '[':
return this._readNamedGraphBlankLabel;
default:
return this._error('Invalid graph label', token);
}
}
} // ### `_readNamedGraphLabel` reads a blank node label of a named graph
// ### `_readNamedGraphLabel` reads a blank node label of a named graph
_readNamedGraphBlankLabel(token) {
if (token.type !== ']')
return this._error('Invalid graph label', token);
if (token.type !== ']') return this._error('Invalid graph label', token);
this._subject = this._blank();
return this._readGraph;
}
} // ### `_readDeclarationPunctuation` reads the punctuation of a declaration
// ### `_readDeclarationPunctuation` reads the punctuation of a declaration
_readDeclarationPunctuation(token) {

@@ -659,140 +704,142 @@ // SPARQL-style declarations don't have punctuation

if (token.type !== '.')
return this._error('Expected declaration to end with a dot', token);
if (token.type !== '.') return this._error('Expected declaration to end with a dot', token);
return this._readInTopContext;
}
} // Reads a list of quantified symbols from a @forSome or @forAll statement
// Reads a list of quantified symbols from a @forSome or @forAll statement
_readQuantifierList(token) {
var entity;
switch (token.type) {
case 'IRI':
case 'prefixed':
if ((entity = this._readEntity(token, true)) !== undefined)
break;
default:
return this._error('Unexpected ' + token.type, token);
}
// Without explicit quantifiers, map entities to a quantified entity
if (!this._explicitQuantifiers)
this._quantified[entity.id] = this._quantifier('b' + blankNodeCount++);
// With explicit quantifiers, output the reified quantifier
case 'IRI':
case 'prefixed':
if ((entity = this._readEntity(token, true)) !== undefined) break;
default:
return this._error('Unexpected ' + token.type, token);
} // Without explicit quantifiers, map entities to a quantified entity
if (!this._explicitQuantifiers) this._quantified[entity.id] = this._quantifier('b' + blankNodeCount++); // With explicit quantifiers, output the reified quantifier
else {
// If this is the first item, start a new quantifier list
if (this._subject === null)
this._emit(this._graph || this.DEFAULTGRAPH, this._predicate,
this._subject = this._blank(), this.QUANTIFIERS_GRAPH);
// Otherwise, continue the previous list
else
this._emit(this._subject, this.RDF_REST,
this._subject = this._blank(), this.QUANTIFIERS_GRAPH);
// Output the list item
this._emit(this._subject, this.RDF_FIRST, entity, this.QUANTIFIERS_GRAPH);
}
// If this is the first item, start a new quantifier list
if (this._subject === null) this._emit(this._graph || this.DEFAULTGRAPH, this._predicate, this._subject = this._blank(), this.QUANTIFIERS_GRAPH); // Otherwise, continue the previous list
else this._emit(this._subject, this.RDF_REST, this._subject = this._blank(), this.QUANTIFIERS_GRAPH); // Output the list item
this._emit(this._subject, this.RDF_FIRST, entity, this.QUANTIFIERS_GRAPH);
}
return this._readQuantifierPunctuation;
}
} // Reads punctuation from a @forSome or @forAll statement
// Reads punctuation from a @forSome or @forAll statement
_readQuantifierPunctuation(token) {
// Read more quantifiers
if (token.type === ',')
return this._readQuantifierList;
// End of the quantifier list
if (token.type === ',') return this._readQuantifierList; // End of the quantifier list
else {
// With explicit quantifiers, close the quantifier list
if (this._explicitQuantifiers) {
this._emit(this._subject, this.RDF_REST, this.RDF_NIL, this.QUANTIFIERS_GRAPH);
this._subject = null;
// With explicit quantifiers, close the quantifier list
if (this._explicitQuantifiers) {
this._emit(this._subject, this.RDF_REST, this.RDF_NIL, this.QUANTIFIERS_GRAPH);
this._subject = null;
} // Read a dot
this._readCallback = this._getContextEndReader();
return this._readCallback(token);
}
// Read a dot
this._readCallback = this._getContextEndReader();
return this._readCallback(token);
}
}
} // ### `_getPathReader` reads a potential path and then resumes with the given function
// ### `_getPathReader` reads a potential path and then resumes with the given function
_getPathReader(afterPath) {
this._afterPath = afterPath;
return this._readPath;
}
} // ### `_readPath` reads a potential path
// ### `_readPath` reads a potential path
_readPath(token) {
switch (token.type) {
// Forward path
case '!': return this._readForwardPath;
// Backward path
case '^': return this._readBackwardPath;
// Not a path; resume reading where we left off
default:
var stack = this._contextStack, parent = stack.length && stack[stack.length - 1];
// If we were reading a list item, we still need to output it
if (parent && parent.type === 'item') {
// The list item is the remaining subejct after reading the path
var item = this._subject;
// Switch back to the context of the list
this._restoreContext();
// Output the list item
this._emit(this._subject, this.RDF_FIRST, item, this._graph);
}
return this._afterPath(token);
// Forward path
case '!':
return this._readForwardPath;
// Backward path
case '^':
return this._readBackwardPath;
// Not a path; resume reading where we left off
default:
var stack = this._contextStack,
parent = stack.length && stack[stack.length - 1]; // If we were reading a list item, we still need to output it
if (parent && parent.type === 'item') {
// The list item is the remaining subejct after reading the path
var item = this._subject; // Switch back to the context of the list
this._restoreContext(); // Output the list item
this._emit(this._subject, this.RDF_FIRST, item, this._graph);
}
return this._afterPath(token);
}
}
} // ### `_readForwardPath` reads a '!' path
// ### `_readForwardPath` reads a '!' path
_readForwardPath(token) {
var subject, predicate, object = this._blank();
// The next token is the predicate
if ((predicate = this._readEntity(token)) === undefined)
return;
// If we were reading a subject, replace the subject by the path's object
if (this._predicate === null)
subject = this._subject, this._subject = object;
// If we were reading an object, replace the subject by the path's object
else
subject = this._object, this._object = object;
// Emit the path's current quad and read its next section
var subject,
predicate,
object = this._blank(); // The next token is the predicate
if ((predicate = this._readEntity(token)) === undefined) return; // If we were reading a subject, replace the subject by the path's object
if (this._predicate === null) subject = this._subject, this._subject = object; // If we were reading an object, replace the subject by the path's object
else subject = this._object, this._object = object; // Emit the path's current quad and read its next section
this._emit(subject, predicate, object, this._graph);
return this._readPath;
}
} // ### `_readBackwardPath` reads a '^' path
// ### `_readBackwardPath` reads a '^' path
_readBackwardPath(token) {
var subject = this._blank(), predicate, object;
// The next token is the predicate
if ((predicate = this._readEntity(token)) === undefined)
return;
// If we were reading a subject, replace the subject by the path's subject
if (this._predicate === null)
object = this._subject, this._subject = subject;
// If we were reading an object, replace the subject by the path's subject
else
object = this._object, this._object = subject;
// Emit the path's current quad and read its next section
var subject = this._blank(),
predicate,
object; // The next token is the predicate
if ((predicate = this._readEntity(token)) === undefined) return; // If we were reading a subject, replace the subject by the path's subject
if (this._predicate === null) object = this._subject, this._subject = subject; // If we were reading an object, replace the subject by the path's subject
else object = this._object, this._object = subject; // Emit the path's current quad and read its next section
this._emit(subject, predicate, object, this._graph);
return this._readPath;
}
} // ### `_getContextEndReader` gets the next reader function at the end of a context
// ### `_getContextEndReader` gets the next reader function at the end of a context
_getContextEndReader() {
var contextStack = this._contextStack;
if (!contextStack.length)
return this._readPunctuation;
if (!contextStack.length) return this._readPunctuation;
switch (contextStack[contextStack.length - 1].type) {
case 'blank':
return this._readBlankNodeTail;
case 'list':
return this._readListItem;
case 'formula':
return this._readFormulaTail;
case 'blank':
return this._readBlankNodeTail;
case 'list':
return this._readListItem;
case 'formula':
return this._readFormulaTail;
}
}
} // ### `_emit` sends a quad through the callback
// ### `_emit` sends a quad through the callback
_emit(subject, predicate, object, graph) {
this._callback(null, this._quad(subject, predicate, object, graph || this.DEFAULTGRAPH));
}
} // ### `_error` emits an error message through the callback
// ### `_error` emits an error message through the callback
_error(message, token) {

@@ -803,166 +850,183 @@ var err = new Error(message + ' on line ' + token.line + '.');

line: token.line,
previousToken: this._lexer.previousToken,
previousToken: this._lexer.previousToken
};
this._callback(err);
this._callback = noop;
}
} // ### `_resolveIRI` resolves an IRI against the base path
// ### `_resolveIRI` resolves an IRI against the base path
_resolveIRI(iri) {
return /^[a-z][a-z0-9+.-]*:/i.test(iri) ? iri : this._resolveRelativeIRI(iri);
}
} // ### `_resolveRelativeIRI` resolves an IRI against the base path,
// assuming that a base path has been set and that the IRI is indeed relative
// ### `_resolveRelativeIRI` resolves an IRI against the base path,
// assuming that a base path has been set and that the IRI is indeed relative
_resolveRelativeIRI(iri) {
// An empty relative IRI indicates the base IRI
if (!iri.length)
return this._base;
// Decide resolving strategy based in the first character
if (!iri.length) return this._base; // Decide resolving strategy based in the first character
switch (iri[0]) {
// Resolve relative fragment IRIs against the base IRI
case '#': return this._base + iri;
// Resolve relative query string IRIs by replacing the query string
case '?': return this._base.replace(/(?:\?.*)?$/, iri);
// Resolve root-relative IRIs at the root of the base IRI
case '/':
// Resolve scheme-relative IRIs to the scheme
return (iri[1] === '/' ? this._baseScheme : this._baseRoot) + this._removeDotSegments(iri);
// Resolve all other IRIs at the base IRI's path
default:
// Relative IRIs cannot contain a colon in the first path segment
return (/^[^/:]*:/.test(iri)) ? '' : this._removeDotSegments(this._basePath + iri);
// Resolve relative fragment IRIs against the base IRI
case '#':
return this._base + iri;
// Resolve relative query string IRIs by replacing the query string
case '?':
return this._base.replace(/(?:\?.*)?$/, iri);
// Resolve root-relative IRIs at the root of the base IRI
case '/':
// Resolve scheme-relative IRIs to the scheme
return (iri[1] === '/' ? this._baseScheme : this._baseRoot) + this._removeDotSegments(iri);
// Resolve all other IRIs at the base IRI's path
default:
// Relative IRIs cannot contain a colon in the first path segment
return /^[^/:]*:/.test(iri) ? '' : this._removeDotSegments(this._basePath + iri);
}
}
} // ### `_removeDotSegments` resolves './' and '../' path segments in an IRI as per RFC3986
// ### `_removeDotSegments` resolves './' and '../' path segments in an IRI as per RFC3986
_removeDotSegments(iri) {
// Don't modify the IRI if it does not contain any dot segments
if (!/(^|\/)\.\.?($|[/#?])/.test(iri))
return iri;
if (!/(^|\/)\.\.?($|[/#?])/.test(iri)) return iri; // Start with an imaginary slash before the IRI in order to resolve trailing './' and '../'
// Start with an imaginary slash before the IRI in order to resolve trailing './' and '../'
var result = '', length = iri.length, i = -1, pathStart = -1, segmentStart = 0, next = '/';
var result = '',
length = iri.length,
i = -1,
pathStart = -1,
segmentStart = 0,
next = '/';
while (i < length) {
switch (next) {
// The path starts with the first slash after the authority
case ':':
if (pathStart < 0) {
// Skip two slashes before the authority
if (iri[++i] === '/' && iri[++i] === '/')
// Skip to slash after the authority
while ((pathStart = i + 1) < length && iri[pathStart] !== '/')
i = pathStart;
}
break;
// Don't modify a query string or fragment
case '?':
case '#':
i = length;
break;
// Handle '/.' or '/..' path segments
case '/':
if (iri[i + 1] === '.') {
next = iri[++i + 1];
switch (next) {
// Remove a '/.' segment
case '/':
result += iri.substring(segmentStart, i - 1);
segmentStart = i + 1;
break;
// Remove a trailing '/.' segment
case undefined:
case '?':
case '#':
return result + iri.substring(segmentStart, i) + iri.substr(i + 1);
// Remove a '/..' segment
case '.':
// The path starts with the first slash after the authority
case ':':
if (pathStart < 0) {
// Skip two slashes before the authority
if (iri[++i] === '/' && iri[++i] === '/') // Skip to slash after the authority
while ((pathStart = i + 1) < length && iri[pathStart] !== '/') i = pathStart;
}
break;
// Don't modify a query string or fragment
case '?':
case '#':
i = length;
break;
// Handle '/.' or '/..' path segments
case '/':
if (iri[i + 1] === '.') {
next = iri[++i + 1];
if (next === undefined || next === '/' || next === '?' || next === '#') {
result += iri.substring(segmentStart, i - 2);
// Try to remove the parent path from result
if ((segmentStart = result.lastIndexOf('/')) >= pathStart)
result = result.substr(0, segmentStart);
// Remove a trailing '/..' segment
if (next !== '/')
return result + '/' + iri.substr(i + 1);
segmentStart = i + 1;
switch (next) {
// Remove a '/.' segment
case '/':
result += iri.substring(segmentStart, i - 1);
segmentStart = i + 1;
break;
// Remove a trailing '/.' segment
case undefined:
case '?':
case '#':
return result + iri.substring(segmentStart, i) + iri.substr(i + 1);
// Remove a '/..' segment
case '.':
next = iri[++i + 1];
if (next === undefined || next === '/' || next === '?' || next === '#') {
result += iri.substring(segmentStart, i - 2); // Try to remove the parent path from result
if ((segmentStart = result.lastIndexOf('/')) >= pathStart) result = result.substr(0, segmentStart); // Remove a trailing '/..' segment
if (next !== '/') return result + '/' + iri.substr(i + 1);
segmentStart = i + 1;
}
}
}
}
}
next = iri[++i];
}
return result + iri.substring(segmentStart);
}
} // ## Public methods
// ### `parse` parses the N3 input and emits each parsed quad through the callback
// ## Public methods
// ### `parse` parses the N3 input and emits each parsed quad through the callback
parse(input, quadCallback, prefixCallback) {
var self = this;
// The read callback is the next function to be executed when a token arrives.
var self = this; // The read callback is the next function to be executed when a token arrives.
// We start reading in the top context.
this._readCallback = this._readInTopContext;
this._sparqlStyle = false;
this._prefixes = Object.create(null);
this._prefixes._ = this._blankNodePrefix ? this._blankNodePrefix.substr(2)
: 'b' + blankNodePrefix++ + '_';
this._prefixes._ = this._blankNodePrefix ? this._blankNodePrefix.substr(2) : 'b' + blankNodePrefix++ + '_';
this._prefixCallback = prefixCallback || noop;
this._inversePredicate = false;
this._quantified = Object.create(null);
this._quantified = Object.create(null); // Parse synchronously if no quad callback is given
// Parse synchronously if no quad callback is given
if (!quadCallback) {
var quads = [], error;
this._callback = function (e, t) { e ? (error = e) : t && quads.push(t); };
var quads = [],
error;
this._callback = function (e, t) {
e ? error = e : t && quads.push(t);
};
this._lexer.tokenize(input).every(function (token) {
return self._readCallback = self._readCallback(token);
});
if (error) throw error;
return quads;
}
} // Parse asynchronously otherwise, executing the read callback when a token arrives
// Parse asynchronously otherwise, executing the read callback when a token arrives
this._callback = quadCallback;
this._lexer.tokenize(input, function (error, token) {
if (error !== null)
self._callback(error), self._callback = noop;
else if (self._readCallback)
self._readCallback = self._readCallback(token);
if (error !== null) self._callback(error), self._callback = noop;else if (self._readCallback) self._readCallback = self._readCallback(token);
});
}
}
// The empty function
function noop() {}
} // The empty function
// Initializes the parser with the given data factory
exports.default = N3Parser;
function noop() {} // Initializes the parser with the given data factory
function initDataFactory(parser, factory) {
// Set factory methods
var namedNode = factory.namedNode;
parser._namedNode = namedNode;
parser._blankNode = factory.blankNode;
parser._literal = factory.literal;
parser._variable = factory.variable;
parser._quad = factory.quad;
parser.DEFAULTGRAPH = factory.defaultGraph();
parser._namedNode = namedNode;
parser._blankNode = factory.blankNode;
parser._literal = factory.literal;
parser._variable = factory.variable;
parser._quad = factory.quad;
parser.DEFAULTGRAPH = factory.defaultGraph(); // Set common named nodes
// Set common named nodes
parser.RDF_FIRST = namedNode(namespaces.rdf.first);
parser.RDF_REST = namedNode(namespaces.rdf.rest);
parser.RDF_NIL = namedNode(namespaces.rdf.nil);
parser.N3_FORALL = namedNode(namespaces.r.forAll);
parser.N3_FORSOME = namedNode(namespaces.r.forSome);
parser.RDF_FIRST = namedNode(_IRIs.default.rdf.first);
parser.RDF_REST = namedNode(_IRIs.default.rdf.rest);
parser.RDF_NIL = namedNode(_IRIs.default.rdf.nil);
parser.N3_FORALL = namedNode(_IRIs.default.r.forAll);
parser.N3_FORSOME = namedNode(_IRIs.default.r.forSome);
parser.ABBREVIATIONS = {
'a': namedNode(namespaces.rdf.type),
'=': namedNode(namespaces.owl.sameAs),
'>': namedNode(namespaces.log.implies),
'a': namedNode(_IRIs.default.rdf.type),
'=': namedNode(_IRIs.default.owl.sameAs),
'>': namedNode(_IRIs.default.log.implies)
};
parser.QUANTIFIERS_GRAPH = namedNode('urn:n3:quantifiers');
}
initDataFactory(N3Parser.prototype, DataFactory);
// ## Exports
module.exports = N3Parser;
initDataFactory(N3Parser.prototype, _N3DataFactory.default);

@@ -0,83 +1,90 @@

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _N3DataFactory = _interopRequireDefault(require("./N3DataFactory"));
var _stream = require("stream");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// **N3Store** objects store N3 quads by graph in memory.
const {
toId,
fromId
} = _N3DataFactory.default.internal; // ## Constructor
var DataFactory = require('./N3DataFactory'),
Readable = require('stream').Readable;
var toId = DataFactory.internal.toId,
fromId = DataFactory.internal.fromId;
// ## Constructor
class N3Store {
constructor(quads, options) {
// The number of quads is initially zero
this._size = 0;
// `_graphs` contains subject, predicate, and object indexes per graph
this._graphs = Object.create(null);
// `_ids` maps entities such as `http://xmlns.com/foaf/0.1/name` to numbers,
this._size = 0; // `_graphs` contains subject, predicate, and object indexes per graph
this._graphs = Object.create(null); // `_ids` maps entities such as `http://xmlns.com/foaf/0.1/name` to numbers,
// saving memory by using only numbers as keys in `_graphs`
this._id = 0;
this._ids = Object.create(null);
this._ids['><'] = 0; // dummy entry, so the first actual key is non-zero
this._entities = Object.create(null); // inverse of `_ids`
// `_blankNodeIndex` is the index of the last automatically named blank node
this._blankNodeIndex = 0;
// Shift parameters if `quads` is not given
if (!options && quads && !quads[0])
options = quads, quads = null;
this._blankNodeIndex = 0; // Shift parameters if `quads` is not given
if (!options && quads && !quads[0]) options = quads, quads = null;
options = options || {};
this._factory = options.factory || DataFactory;
this._factory = options.factory || _N3DataFactory.default; // Add quads if passed
// Add quads if passed
if (quads)
this.addQuads(quads);
}
if (quads) this.addQuads(quads);
} // ## Public properties
// ### `size` returns the number of quads in the store
// ## Public properties
// ### `size` returns the number of quads in the store
get size() {
// Return the quad count if if was cached
var size = this._size;
if (size !== null)
return size;
if (size !== null) return size; // Calculate the number of quads by counting to the deepest level
// Calculate the number of quads by counting to the deepest level
size = 0;
var graphs = this._graphs, subjects, subject;
for (var graphKey in graphs)
for (var subjectKey in (subjects = graphs[graphKey].subjects))
for (var predicateKey in (subject = subjects[subjectKey]))
size += Object.keys(subject[predicateKey]).length;
return this._size = size;
}
var graphs = this._graphs,
subjects,
subject;
// ## Private methods
for (var graphKey in graphs) for (var subjectKey in subjects = graphs[graphKey].subjects) for (var predicateKey in subject = subjects[subjectKey]) size += Object.keys(subject[predicateKey]).length;
return this._size = size;
} // ## Private methods
// ### `_addToIndex` adds a quad to a three-layered index.
// Returns if the index has changed, if the entry did not already exist.
_addToIndex(index0, key0, key1, key2) {
// Create layers as necessary
var index1 = index0[key0] || (index0[key0] = {});
var index2 = index1[key1] || (index1[key1] = {});
// Setting the key to _any_ value signals the presence of the quad
var index2 = index1[key1] || (index1[key1] = {}); // Setting the key to _any_ value signals the presence of the quad
var existed = key2 in index2;
if (!existed)
index2[key2] = null;
if (!existed) index2[key2] = null;
return !existed;
}
} // ### `_removeFromIndex` removes a quad from a three-layered index
// ### `_removeFromIndex` removes a quad from a three-layered index
_removeFromIndex(index0, key0, key1, key2) {
// Remove the quad from the index
var index1 = index0[key0], index2 = index1[key1], key;
delete index2[key2];
var index1 = index0[key0],
index2 = index1[key1],
key;
delete index2[key2]; // Remove intermediary index layers if they are empty
// Remove intermediary index layers if they are empty
for (key in index2) return;
delete index1[key1];
for (key in index1) return;
delete index0[key0];
}
// ### `_findInIndex` finds a set of quads in a three-layered index.
} // ### `_findInIndex` finds a set of quads in a three-layered index.
// The index base is `index0` and the keys at each level are `key0`, `key1`, and `key2`.

@@ -92,9 +99,14 @@ // Any of these keys can be undefined, which is interpreted as a wildcard.

// If instead `array` is given, each result is added to the array.
_findInIndex(index0, key0, key1, key2, name0, name1, name2, graph, callback, array) {
var tmp, index1, index2, varCount = !key0 + !key1 + !key2,
var tmp,
index1,
index2,
varCount = !key0 + !key1 + !key2,
// depending on the number of variables, keys or reverse index are faster
entityKeys = varCount > 1 ? Object.keys(this._ids) : this._entities;
entityKeys = varCount > 1 ? Object.keys(this._ids) : this._entities; // If a key is specified, use only that part of index 0.
// If a key is specified, use only that part of index 0.
if (key0) (tmp = index0, index0 = {})[key0] = tmp[key0];
for (var value0 in index0) {

@@ -106,2 +118,3 @@ var entity0 = entityKeys[value0];

if (key1) (tmp = index1, index1 = {})[key1] = tmp[key1];
for (var value1 in index1) {

@@ -112,15 +125,17 @@ var entity1 = entityKeys[value1];

// If a key is specified, use only that part of index 2, if it exists.
var values = key2 ? (key2 in index2 ? [key2] : []) : Object.keys(index2);
// Create quads for all items found in index 2.
var values = key2 ? key2 in index2 ? [key2] : [] : Object.keys(index2); // Create quads for all items found in index 2.
for (var l = 0; l < values.length; l++) {
var parts = { subject: null, predicate: null, object: null };
var parts = {
subject: null,
predicate: null,
object: null
};
parts[name0] = fromId(entity0, this._factory);
parts[name1] = fromId(entity1, this._factory);
parts[name2] = fromId(entityKeys[values[l]], this._factory);
var quad = this._factory.quad(
parts.subject, parts.predicate, parts.object, fromId(graph, this._factory));
if (array)
array.push(quad);
else if (callback(quad))
return true;
var quad = this._factory.quad(parts.subject, parts.predicate, parts.object, fromId(graph, this._factory));
if (array) array.push(quad);else if (callback(quad)) return true;
}

@@ -131,47 +146,50 @@ }

}
return array;
}
} // ### `_loop` executes the callback on all keys of index 0
// ### `_loop` executes the callback on all keys of index 0
_loop(index0, callback) {
for (var key0 in index0)
callback(key0);
}
for (var key0 in index0) callback(key0);
} // ### `_loopByKey0` executes the callback on all keys of a certain entry in index 0
// ### `_loopByKey0` executes the callback on all keys of a certain entry in index 0
_loopByKey0(index0, key0, callback) {
var index1, key1;
if (index1 = index0[key0]) {
for (key1 in index1)
callback(key1);
for (key1 in index1) callback(key1);
}
}
} // ### `_loopByKey1` executes the callback on given keys of all entries in index 0
// ### `_loopByKey1` executes the callback on given keys of all entries in index 0
_loopByKey1(index0, key1, callback) {
var key0, index1;
for (key0 in index0) {
index1 = index0[key0];
if (index1[key1])
callback(key0);
if (index1[key1]) callback(key0);
}
}
} // ### `_loopBy2Keys` executes the callback on given keys of certain entries in index 2
// ### `_loopBy2Keys` executes the callback on given keys of certain entries in index 2
_loopBy2Keys(index0, key0, key1, callback) {
var index1, index2, key2;
if ((index1 = index0[key0]) && (index2 = index1[key1])) {
for (key2 in index2)
callback(key2);
for (key2 in index2) callback(key2);
}
}
// ### `_countInIndex` counts matching quads in a three-layered index.
} // ### `_countInIndex` counts matching quads in a three-layered index.
// The index base is `index0` and the keys at each level are `key0`, `key1`, and `key2`.
// Any of these keys can be undefined, which is interpreted as a wildcard.
_countInIndex(index0, key0, key1, key2) {
var count = 0, tmp, index1, index2;
var count = 0,
tmp,
index1,
index2; // If a key is specified, count only that part of index 0
// If a key is specified, count only that part of index 0
if (key0) (tmp = index0, index0 = {})[key0] = tmp[key0];
for (var value0 in index0) {

@@ -181,7 +199,7 @@ if (index1 = index0[value0]) {

if (key1) (tmp = index1, index1 = {})[key1] = tmp[key1];
for (var value1 in index1) {
if (index2 = index1[value1]) {
// If a key is specified, count the quad if it exists
if (key2) (key2 in index2) && count++;
// Otherwise, count all quads
if (key2) key2 in index2 && count++; // Otherwise, count all quads
else count += Object.keys(index2).length;

@@ -192,19 +210,20 @@ }

}
return count;
}
} // ### `_getGraphs` returns an array with the given graph,
// or all graphs if the argument is null or undefined.
// ### `_getGraphs` returns an array with the given graph,
// or all graphs if the argument is null or undefined.
_getGraphs(graph) {
if (!isString(graph))
return this._graphs;
if (!isString(graph)) return this._graphs;
var graphs = {};
graphs[graph] = this._graphs[graph];
return graphs;
}
} // ### `_uniqueEntities` returns a function that accepts an entity ID
// and passes the corresponding entity to callback if it hasn't occurred before.
// ### `_uniqueEntities` returns a function that accepts an entity ID
// and passes the corresponding entity to callback if it hasn't occurred before.
_uniqueEntities(callback) {
var uniqueIds = Object.create(null), entities = this._entities;
var uniqueIds = Object.create(null),
entities = this._entities;
return function (id) {

@@ -216,122 +235,122 @@ if (!(id in uniqueIds)) {

};
}
} // ## Public methods
// ### `addQuad` adds a new quad to the store.
// Returns if the quad index has changed, if the quad did not already exist.
// ## Public methods
// ### `addQuad` adds a new quad to the store.
// Returns if the quad index has changed, if the quad did not already exist.
addQuad(subject, predicate, object, graph) {
// Shift arguments if a quad object is given instead of components
if (!predicate)
graph = subject.graph, object = subject.object,
predicate = subject.predicate, subject = subject.subject;
if (!predicate) graph = subject.graph, object = subject.object, predicate = subject.predicate, subject = subject.subject; // Convert terms to internal string representation
// Convert terms to internal string representation
subject = toId(subject);
predicate = toId(predicate);
object = toId(object);
graph = toId(graph);
graph = toId(graph); // Find the graph that will contain the triple
// Find the graph that will contain the triple
var graphItem = this._graphs[graph];
// Create the graph if it doesn't exist yet
var graphItem = this._graphs[graph]; // Create the graph if it doesn't exist yet
if (!graphItem) {
graphItem = this._graphs[graph] = { subjects: {}, predicates: {}, objects: {} };
// Freezing a graph helps subsequent `add` performance,
graphItem = this._graphs[graph] = {
subjects: {},
predicates: {},
objects: {}
}; // Freezing a graph helps subsequent `add` performance,
// and properties will never be modified anyway
Object.freeze(graphItem);
}
// Since entities can often be long IRIs, we avoid storing them in every index.
} // Since entities can often be long IRIs, we avoid storing them in every index.
// Instead, we have a separate index that maps entities to numbers,
// which are then used as keys in the other indexes.
var ids = this._ids;
var entities = this._entities;
subject = ids[subject] || (ids[entities[++this._id] = subject] = this._id);
subject = ids[subject] || (ids[entities[++this._id] = subject] = this._id);
predicate = ids[predicate] || (ids[entities[++this._id] = predicate] = this._id);
object = ids[object] || (ids[entities[++this._id] = object] = this._id);
object = ids[object] || (ids[entities[++this._id] = object] = this._id);
var changed = this._addToIndex(graphItem.subjects, subject, predicate, object);
this._addToIndex(graphItem.predicates, predicate, object, subject);
this._addToIndex(graphItem.objects, object, subject, predicate);
var changed = this._addToIndex(graphItem.subjects, subject, predicate, object);
// The cached quad count is now invalid
this._addToIndex(graphItem.predicates, predicate, object, subject);
this._addToIndex(graphItem.objects, object, subject, predicate); // The cached quad count is now invalid
this._size = null;
return changed;
}
} // ### `addQuads` adds multiple quads to the store
// ### `addQuads` adds multiple quads to the store
addQuads(quads) {
for (var i = 0; i < quads.length; i++)
this.addQuad(quads[i]);
}
for (var i = 0; i < quads.length; i++) this.addQuad(quads[i]);
} // ### `import` adds a stream of quads to the store
// ### `import` adds a stream of quads to the store
import(stream) {
var self = this;
stream.on('data', function (quad) { self.addQuad(quad); });
stream.on('data', function (quad) {
self.addQuad(quad);
});
return stream;
}
} // ### `removeQuad` removes a quad from the store if it exists
// ### `removeQuad` removes a quad from the store if it exists
removeQuad(subject, predicate, object, graph) {
// Shift arguments if a quad object is given instead of components
if (!predicate)
graph = subject.graph, object = subject.object,
predicate = subject.predicate, subject = subject.subject;
if (!predicate) graph = subject.graph, object = subject.object, predicate = subject.predicate, subject = subject.subject; // Convert terms to internal string representation
// Convert terms to internal string representation
subject = toId(subject);
predicate = toId(predicate);
object = toId(object);
graph = toId(graph);
// Find internal identifiers for all components
graph = toId(graph); // Find internal identifiers for all components
// and verify the quad exists.
var graphItem, ids = this._ids, graphs = this._graphs, subjects, predicates;
if (!(subject = ids[subject]) || !(predicate = ids[predicate]) ||
!(object = ids[object]) || !(graphItem = graphs[graph]) ||
!(subjects = graphItem.subjects[subject]) ||
!(predicates = subjects[predicate]) ||
!(object in predicates))
return false;
// Remove it from all indexes
this._removeFromIndex(graphItem.subjects, subject, predicate, object);
this._removeFromIndex(graphItem.predicates, predicate, object, subject);
this._removeFromIndex(graphItem.objects, object, subject, predicate);
if (this._size !== null) this._size--;
var graphItem,
ids = this._ids,
graphs = this._graphs,
subjects,
predicates;
if (!(subject = ids[subject]) || !(predicate = ids[predicate]) || !(object = ids[object]) || !(graphItem = graphs[graph]) || !(subjects = graphItem.subjects[subject]) || !(predicates = subjects[predicate]) || !(object in predicates)) return false; // Remove it from all indexes
// Remove the graph if it is empty
this._removeFromIndex(graphItem.subjects, subject, predicate, object);
this._removeFromIndex(graphItem.predicates, predicate, object, subject);
this._removeFromIndex(graphItem.objects, object, subject, predicate);
if (this._size !== null) this._size--; // Remove the graph if it is empty
for (subject in graphItem.subjects) return true;
delete graphs[graph];
return true;
}
} // ### `removeQuads` removes multiple quads from the store
// ### `removeQuads` removes multiple quads from the store
removeQuads(quads) {
for (var i = 0; i < quads.length; i++)
this.removeQuad(quads[i]);
}
for (var i = 0; i < quads.length; i++) this.removeQuad(quads[i]);
} // ### `remove` removes a stream of quads from the store
// ### `remove` removes a stream of quads from the store
remove(stream) {
var self = this;
stream.on('data', function (quad) { self.removeQuad(quad); });
stream.on('data', function (quad) {
self.removeQuad(quad);
});
return stream;
}
} // ### `removeMatches` removes all matching quads from the store
// Setting any field to `undefined` or `null` indicates a wildcard.
// ### `removeMatches` removes all matching quads from the store
// Setting any field to `undefined` or `null` indicates a wildcard.
removeMatches(subject, predicate, object, graph) {
return this.remove(this.match(subject, predicate, object, graph));
}
} // ### `deleteGraph` removes all triples with the given graph from the store
// ### `deleteGraph` removes all triples with the given graph from the store
deleteGraph(graph) {
return this.removeMatches(null, null, null, graph);
}
} // ### `getQuads` returns an array of quads matching a pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
// ### `getQuads` returns an array of quads matching a pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
getQuads(subject, predicate, object, graph) {

@@ -344,11 +363,13 @@ // Convert terms to internal string representation

var quads = [], graphs = this._getGraphs(graph), content,
ids = this._ids, subjectId, predicateId, objectId;
var quads = [],
graphs = this._getGraphs(graph),
content,
ids = this._ids,
subjectId,
predicateId,
objectId; // Translate IRIs to internal index keys.
// Translate IRIs to internal index keys.
if (isString(subject) && !(subjectId = ids[subject]) ||
isString(predicate) && !(predicateId = ids[predicate]) ||
isString(object) && !(objectId = ids[object]))
return quads;
if (isString(subject) && !(subjectId = ids[subject]) || isString(predicate) && !(predicateId = ids[predicate]) || isString(object) && !(objectId = ids[object])) return quads;
for (var graphId in graphs) {

@@ -359,41 +380,32 @@ // Only if the specified graph contains triples, there can be results

if (subjectId) {
if (objectId)
// If subject and object are given, the object index will be the fastest
this._findInIndex(content.objects, objectId, subjectId, predicateId,
'object', 'subject', 'predicate', graphId, null, quads);
else
// If only subject and possibly predicate are given, the subject index will be the fastest
this._findInIndex(content.subjects, subjectId, predicateId, null,
'subject', 'predicate', 'object', graphId, null, quads);
}
else if (predicateId)
// If only predicate and possibly object are given, the predicate index will be the fastest
this._findInIndex(content.predicates, predicateId, objectId, null,
'predicate', 'object', 'subject', graphId, null, quads);
else if (objectId)
// If only object is given, the object index will be the fastest
this._findInIndex(content.objects, objectId, null, null,
'object', 'subject', 'predicate', graphId, null, quads);
else
// If nothing is given, iterate subjects and predicates first
this._findInIndex(content.subjects, null, null, null,
'subject', 'predicate', 'object', graphId, null, quads);
if (objectId) // If subject and object are given, the object index will be the fastest
this._findInIndex(content.objects, objectId, subjectId, predicateId, 'object', 'subject', 'predicate', graphId, null, quads);else // If only subject and possibly predicate are given, the subject index will be the fastest
this._findInIndex(content.subjects, subjectId, predicateId, null, 'subject', 'predicate', 'object', graphId, null, quads);
} else if (predicateId) // If only predicate and possibly object are given, the predicate index will be the fastest
this._findInIndex(content.predicates, predicateId, objectId, null, 'predicate', 'object', 'subject', graphId, null, quads);else if (objectId) // If only object is given, the object index will be the fastest
this._findInIndex(content.objects, objectId, null, null, 'object', 'subject', 'predicate', graphId, null, quads);else // If nothing is given, iterate subjects and predicates first
this._findInIndex(content.subjects, null, null, null, 'subject', 'predicate', 'object', graphId, null, quads);
}
}
return quads;
}
} // ### `match` returns a stream of quads matching a pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
// ### `match` returns a stream of quads matching a pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
match(subject, predicate, object, graph) {
var self = this;
var stream = new Readable({ objectMode: true });
var stream = new _stream.Readable({
objectMode: true
}); // Initialize stream once it is being read
// Initialize stream once it is being read
stream._read = function () {
stream._read = function () {};
var quads = self.getQuads(subject, predicate, object, graph);
for (var quad of quads) {
stream.push(quad);
}
stream.push(null);

@@ -403,6 +415,6 @@ };

return stream;
}
} // ### `countQuads` returns the number of quads matching a pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
// ### `countQuads` returns the number of quads matching a pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
countQuads(subject, predicate, object, graph) {

@@ -415,11 +427,13 @@ // Convert terms to internal string representation

var count = 0, graphs = this._getGraphs(graph), content,
ids = this._ids, subjectId, predicateId, objectId;
var count = 0,
graphs = this._getGraphs(graph),
content,
ids = this._ids,
subjectId,
predicateId,
objectId; // Translate IRIs to internal index keys.
// Translate IRIs to internal index keys.
if (isString(subject) && !(subjectId = ids[subject]) ||
isString(predicate) && !(predicateId = ids[predicate]) ||
isString(object) && !(objectId = ids[object]))
return 0;
if (isString(subject) && !(subjectId = ids[subject]) || isString(predicate) && !(predicateId = ids[predicate]) || isString(object) && !(objectId = ids[object])) return 0;
for (var graphId in graphs) {

@@ -430,14 +444,9 @@ // Only if the specified graph contains triples, there can be results

if (subject) {
if (object)
// If subject and object are given, the object index will be the fastest
count += this._countInIndex(content.objects, objectId, subjectId, predicateId);
else
// If only subject and possibly predicate are given, the subject index will be the fastest
if (object) // If subject and object are given, the object index will be the fastest
count += this._countInIndex(content.objects, objectId, subjectId, predicateId);else // If only subject and possibly predicate are given, the subject index will be the fastest
count += this._countInIndex(content.subjects, subjectId, predicateId, objectId);
}
else if (predicate) {
} else if (predicate) {
// If only predicate and possibly object are given, the predicate index will be the fastest
count += this._countInIndex(content.predicates, predicateId, objectId, subjectId);
}
else {
} else {
// If only object is possibly given, the object index will be the fastest

@@ -448,7 +457,8 @@ count += this._countInIndex(content.objects, objectId, subjectId, predicateId);

}
return count;
}
} // ### `forEach` executes the callback on all quads.
// Setting any field to `undefined` or `null` indicates a wildcard.
// ### `forEach` executes the callback on all quads.
// Setting any field to `undefined` or `null` indicates a wildcard.
forEach(callback, subject, predicate, object, graph) {

@@ -459,7 +469,7 @@ this.some(function (quad) {

}, subject, predicate, object, graph);
}
// ### `every` executes the callback on all quads,
} // ### `every` executes the callback on all quads,
// and returns `true` if it returns truthy for all them.
// Setting any field to `undefined` or `null` indicates a wildcard.
every(callback, subject, predicate, object, graph) {

@@ -472,7 +482,7 @@ var some = false;

return some && every;
}
// ### `some` executes the callback on all quads,
} // ### `some` executes the callback on all quads,
// and returns `true` if it returns truthy for any of them.
// Setting any field to `undefined` or `null` indicates a wildcard.
some(callback, subject, predicate, object, graph) {

@@ -485,11 +495,12 @@ // Convert terms to internal string representation

var graphs = this._getGraphs(graph), content,
ids = this._ids, subjectId, predicateId, objectId;
var graphs = this._getGraphs(graph),
content,
ids = this._ids,
subjectId,
predicateId,
objectId; // Translate IRIs to internal index keys.
// Translate IRIs to internal index keys.
if (isString(subject) && !(subjectId = ids[subject]) ||
isString(predicate) && !(predicateId = ids[predicate]) ||
isString(object) && !(objectId = ids[object]))
return false;
if (isString(subject) && !(subjectId = ids[subject]) || isString(predicate) && !(predicateId = ids[predicate]) || isString(object) && !(objectId = ids[object])) return false;
for (var graphId in graphs) {

@@ -501,48 +512,38 @@ // Only if the specified graph contains triples, there can be results

if (objectId) {
// If subject and object are given, the object index will be the fastest
if (this._findInIndex(content.objects, objectId, subjectId, predicateId,
'object', 'subject', 'predicate', graphId, callback, null))
return true;
}
else
// If only subject and possibly predicate are given, the subject index will be the fastest
if (this._findInIndex(content.subjects, subjectId, predicateId, null,
'subject', 'predicate', 'object', graphId, callback, null))
return true;
}
else if (predicateId) {
// If subject and object are given, the object index will be the fastest
if (this._findInIndex(content.objects, objectId, subjectId, predicateId, 'object', 'subject', 'predicate', graphId, callback, null)) return true;
} else // If only subject and possibly predicate are given, the subject index will be the fastest
if (this._findInIndex(content.subjects, subjectId, predicateId, null, 'subject', 'predicate', 'object', graphId, callback, null)) return true;
} else if (predicateId) {
// If only predicate and possibly object are given, the predicate index will be the fastest
if (this._findInIndex(content.predicates, predicateId, objectId, null,
'predicate', 'object', 'subject', graphId, callback, null)) {
if (this._findInIndex(content.predicates, predicateId, objectId, null, 'predicate', 'object', 'subject', graphId, callback, null)) {
return true;
}
}
else if (objectId) {
} else if (objectId) {
// If only object is given, the object index will be the fastest
if (this._findInIndex(content.objects, objectId, null, null,
'object', 'subject', 'predicate', graphId, callback, null)) {
if (this._findInIndex(content.objects, objectId, null, null, 'object', 'subject', 'predicate', graphId, callback, null)) {
return true;
}
}
else
// If nothing is given, iterate subjects and predicates first
if (this._findInIndex(content.subjects, null, null, null,
'subject', 'predicate', 'object', graphId, callback, null)) {
return true;
}
} else // If nothing is given, iterate subjects and predicates first
if (this._findInIndex(content.subjects, null, null, null, 'subject', 'predicate', 'object', graphId, callback, null)) {
return true;
}
}
}
return false;
}
} // ### `getSubjects` returns all subjects that match the pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
// ### `getSubjects` returns all subjects that match the pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
getSubjects(predicate, object, graph) {
var results = [];
this.forSubjects(function (s) { results.push(s); }, predicate, object, graph);
this.forSubjects(function (s) {
results.push(s);
}, predicate, object, graph);
return results;
}
} // ### `forSubjects` executes the callback on all subjects that match the pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
// ### `forSubjects` executes the callback on all subjects that match the pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
forSubjects(callback, predicate, object, graph) {

@@ -554,10 +555,12 @@ // Convert terms to internal string representation

var ids = this._ids, graphs = this._getGraphs(graph), content, predicateId, objectId;
callback = this._uniqueEntities(callback);
var ids = this._ids,
graphs = this._getGraphs(graph),
content,
predicateId,
objectId;
// Translate IRIs to internal index keys.
if (isString(predicate) && !(predicateId = ids[predicate]) ||
isString(object) && !(objectId = ids[object]))
return;
callback = this._uniqueEntities(callback); // Translate IRIs to internal index keys.
if (isString(predicate) && !(predicateId = ids[predicate]) || isString(object) && !(objectId = ids[object])) return;
for (graph in graphs) {

@@ -568,29 +571,24 @@ // Only if the specified graph contains triples, there can be results

if (predicateId) {
if (objectId)
// If predicate and object are given, the POS index is best.
this._loopBy2Keys(content.predicates, predicateId, objectId, callback);
else
// If only predicate is given, the SPO index is best.
if (objectId) // If predicate and object are given, the POS index is best.
this._loopBy2Keys(content.predicates, predicateId, objectId, callback);else // If only predicate is given, the SPO index is best.
this._loopByKey1(content.subjects, predicateId, callback);
}
else if (objectId)
// If only object is given, the OSP index is best.
this._loopByKey0(content.objects, objectId, callback);
else
// If no params given, iterate all the subjects
} else if (objectId) // If only object is given, the OSP index is best.
this._loopByKey0(content.objects, objectId, callback);else // If no params given, iterate all the subjects
this._loop(content.subjects, callback);
}
}
}
} // ### `getPredicates` returns all predicates that match the pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
// ### `getPredicates` returns all predicates that match the pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
getPredicates(subject, object, graph) {
var results = [];
this.forPredicates(function (p) { results.push(p); }, subject, object, graph);
this.forPredicates(function (p) {
results.push(p);
}, subject, object, graph);
return results;
}
} // ### `forPredicates` executes the callback on all predicates that match the pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
// ### `forPredicates` executes the callback on all predicates that match the pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
forPredicates(callback, subject, object, graph) {

@@ -602,10 +600,12 @@ // Convert terms to internal string representation

var ids = this._ids, graphs = this._getGraphs(graph), content, subjectId, objectId;
callback = this._uniqueEntities(callback);
var ids = this._ids,
graphs = this._getGraphs(graph),
content,
subjectId,
objectId;
// Translate IRIs to internal index keys.
if (isString(subject) && !(subjectId = ids[subject]) ||
isString(object) && !(objectId = ids[object]))
return;
callback = this._uniqueEntities(callback); // Translate IRIs to internal index keys.
if (isString(subject) && !(subjectId = ids[subject]) || isString(object) && !(objectId = ids[object])) return;
for (graph in graphs) {

@@ -616,29 +616,24 @@ // Only if the specified graph contains triples, there can be results

if (subjectId) {
if (objectId)
// If subject and object are given, the OSP index is best.
this._loopBy2Keys(content.objects, objectId, subjectId, callback);
else
// If only subject is given, the SPO index is best.
if (objectId) // If subject and object are given, the OSP index is best.
this._loopBy2Keys(content.objects, objectId, subjectId, callback);else // If only subject is given, the SPO index is best.
this._loopByKey0(content.subjects, subjectId, callback);
}
else if (objectId)
// If only object is given, the POS index is best.
this._loopByKey1(content.predicates, objectId, callback);
else
// If no params given, iterate all the predicates.
} else if (objectId) // If only object is given, the POS index is best.
this._loopByKey1(content.predicates, objectId, callback);else // If no params given, iterate all the predicates.
this._loop(content.predicates, callback);
}
}
}
} // ### `getObjects` returns all objects that match the pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
// ### `getObjects` returns all objects that match the pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
getObjects(subject, predicate, graph) {
var results = [];
this.forObjects(function (o) { results.push(o); }, subject, predicate, graph);
this.forObjects(function (o) {
results.push(o);
}, subject, predicate, graph);
return results;
}
} // ### `forObjects` executes the callback on all objects that match the pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
// ### `forObjects` executes the callback on all objects that match the pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
forObjects(callback, subject, predicate, graph) {

@@ -650,10 +645,12 @@ // Convert terms to internal string representation

var ids = this._ids, graphs = this._getGraphs(graph), content, subjectId, predicateId;
callback = this._uniqueEntities(callback);
var ids = this._ids,
graphs = this._getGraphs(graph),
content,
subjectId,
predicateId;
// Translate IRIs to internal index keys.
if (isString(subject) && !(subjectId = ids[subject]) ||
isString(predicate) && !(predicateId = ids[predicate]))
return;
callback = this._uniqueEntities(callback); // Translate IRIs to internal index keys.
if (isString(subject) && !(subjectId = ids[subject]) || isString(predicate) && !(predicateId = ids[predicate])) return;
for (graph in graphs) {

@@ -664,29 +661,24 @@ // Only if the specified graph contains triples, there can be results

if (subjectId) {
if (predicateId)
// If subject and predicate are given, the SPO index is best.
this._loopBy2Keys(content.subjects, subjectId, predicateId, callback);
else
// If only subject is given, the OSP index is best.
if (predicateId) // If subject and predicate are given, the SPO index is best.
this._loopBy2Keys(content.subjects, subjectId, predicateId, callback);else // If only subject is given, the OSP index is best.
this._loopByKey1(content.objects, subjectId, callback);
}
else if (predicateId)
// If only predicate is given, the POS index is best.
this._loopByKey0(content.predicates, predicateId, callback);
else
// If no params given, iterate all the objects.
} else if (predicateId) // If only predicate is given, the POS index is best.
this._loopByKey0(content.predicates, predicateId, callback);else // If no params given, iterate all the objects.
this._loop(content.objects, callback);
}
}
}
} // ### `getGraphs` returns all graphs that match the pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
// ### `getGraphs` returns all graphs that match the pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
getGraphs(subject, predicate, object) {
var results = [];
this.forGraphs(function (g) { results.push(g); }, subject, predicate, object);
this.forGraphs(function (g) {
results.push(g);
}, subject, predicate, object);
return results;
}
} // ### `forGraphs` executes the callback on all graphs that match the pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
// ### `forGraphs` executes the callback on all graphs that match the pattern.
// Setting any field to `undefined` or `null` indicates a wildcard.
forGraphs(callback, subject, predicate, object) {

@@ -699,19 +691,20 @@ for (var graph in this._graphs) {

}
}
} // ### `createBlankNode` creates a new blank node, returning its name
// ### `createBlankNode` creates a new blank node, returning its name
createBlankNode(suggestedName) {
var name, index;
// Generate a name based on the suggested name
var name, index; // Generate a name based on the suggested name
if (suggestedName) {
name = suggestedName = '_:' + suggestedName, index = 1;
while (this._ids[name])
name = suggestedName + index++;
}
// Generate a generic blank node name
while (this._ids[name]) name = suggestedName + index++;
} // Generate a generic blank node name
else {
do { name = '_:b' + this._blankNodeIndex++; }
while (this._ids[name]);
}
// Add the blank node to the entities, avoiding the generation of duplicates
do {
name = '_:b' + this._blankNodeIndex++;
} while (this._ids[name]);
} // Add the blank node to the entities, avoiding the generation of duplicates
this._ids[name] = ++this._id;

@@ -721,10 +714,10 @@ this._entities[this._id] = name;

}
}
// Determines whether the argument is a string
} // Determines whether the argument is a string
exports.default = N3Store;
function isString(s) {
return typeof s === 'string' || s instanceof String;
}
// ## Exports
module.exports = N3Store;
}

@@ -0,43 +1,75 @@

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _N3Parser = _interopRequireDefault(require("./N3Parser"));
var _stream = require("stream");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// **N3StreamParser** parses a text stream into a quad stream.
var Transform = require('stream').Transform,
N3Parser = require('./N3Parser.js');
// ## Constructor
class N3StreamParser extends Transform {
class N3StreamParser extends _stream.Transform {
constructor(options) {
super({ decodeStrings: true });
this._readableState.objectMode = true;
super({
decodeStrings: true
});
this._readableState.objectMode = true; // Set up parser with dummy stream to obtain `data` and `end` callbacks
// Set up parser with dummy stream to obtain `data` and `end` callbacks
var self = this, parser = new N3Parser(options), onData, onEnd;
var self = this,
parser = new _N3Parser.default(options),
onData,
onEnd;
parser.parse({
on: function (event, callback) {
switch (event) {
case 'data': onData = callback; break;
case 'end': onEnd = callback; break;
case 'data':
onData = callback;
break;
case 'end':
onEnd = callback;
break;
}
},
},
// Handle quads by pushing them down the pipeline
function (error, quad) { error && self.emit('error', error) || quad && self.push(quad); },
// Emit prefixes through the `prefix` event
function (prefix, uri) { self.emit('prefix', prefix, uri); }
);
}
}, // Handle quads by pushing them down the pipeline
function (error, quad) {
error && self.emit('error', error) || quad && self.push(quad);
}, // Emit prefixes through the `prefix` event
function (prefix, uri) {
self.emit('prefix', prefix, uri);
}); // Implement Transform methods through parser callbacks
// Implement Transform methods through parser callbacks
this._transform = function (chunk, encoding, done) { onData(chunk); done(); };
this._flush = function (done) { onEnd(); done(); };
}
this._transform = function (chunk, encoding, done) {
onData(chunk);
done();
};
// ### Parses a stream of strings
this._flush = function (done) {
onEnd();
done();
};
} // ### Parses a stream of strings
import(stream) {
var self = this;
stream.on('data', function (chunk) { self.write(chunk); });
stream.on('end', function () { self.end(); });
stream.on('error', function (error) { self.emit('error', error); });
stream.on('data', function (chunk) {
self.write(chunk);
});
stream.on('end', function () {
self.end();
});
stream.on('error', function (error) {
self.emit('error', error);
});
return this;
}
}
// ## Exports
module.exports = N3StreamParser;
exports.default = N3StreamParser;

@@ -0,37 +1,64 @@

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _stream = require("stream");
var _N3Writer = _interopRequireDefault(require("./N3Writer"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// **N3StreamWriter** serializes a quad stream into a text stream.
var Transform = require('stream').Transform,
N3Writer = require('./N3Writer.js');
// ## Constructor
class N3StreamWriter extends Transform {
class N3StreamWriter extends _stream.Transform {
constructor(options) {
super({ encoding: 'utf8' });
this._writableState.objectMode = true;
super({
encoding: 'utf8'
});
this._writableState.objectMode = true; // Set up writer with a dummy stream object
// Set up writer with a dummy stream object
var self = this;
var writer = this._writer = new N3Writer({
write: function (quad, encoding, callback) { self.push(quad); callback && callback(); },
end: function (callback) { self.push(null); callback && callback(); },
}, options);
var writer = this._writer = new _N3Writer.default({
write: function (quad, encoding, callback) {
self.push(quad);
callback && callback();
},
end: function (callback) {
self.push(null);
callback && callback();
}
}, options); // Implement Transform methods on top of writer
// Implement Transform methods on top of writer
this._transform = function (quad, encoding, done) { writer.addQuad(quad, done); };
this._flush = function (done) { writer.end(done); };
}
this._transform = function (quad, encoding, done) {
writer.addQuad(quad, done);
};
// ### Serializes a stream of quads
this._flush = function (done) {
writer.end(done);
};
} // ### Serializes a stream of quads
import(stream) {
var self = this;
stream.on('data', function (quad) { self.write(quad); });
stream.on('end', function () { self.end(); });
stream.on('error', function (error) { self.emit('error', error); });
stream.on('prefix', function (prefix, iri) { self._writer.addPrefix(prefix, iri); });
stream.on('data', function (quad) {
self.write(quad);
});
stream.on('end', function () {
self.end();
});
stream.on('error', function (error) {
self.emit('error', error);
});
stream.on('prefix', function (prefix, iri) {
self._writer.addPrefix(prefix, iri);
});
return this;
}
}
// ## Exports
module.exports = N3StreamWriter;
exports.default = N3StreamWriter;

@@ -0,71 +1,85 @@

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.isNamedNode = isNamedNode;
exports.isBlankNode = isBlankNode;
exports.isLiteral = isLiteral;
exports.isVariable = isVariable;
exports.isDefaultGraph = isDefaultGraph;
exports.inDefaultGraph = inDefaultGraph;
exports.prefix = prefix;
exports.prefixes = prefixes;
var _N3DataFactory = _interopRequireDefault(require("./N3DataFactory"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// **N3Util** provides N3 utility functions.
// Tests whether the given term represents an IRI
function isNamedNode(term) {
return !!term && term.termType === 'NamedNode';
} // Tests whether the given term represents a blank node
var DataFactory = require('./N3DataFactory');
var N3Util = {
// Tests whether the given term represents an IRI
isNamedNode: function (term) {
return !!term && term.termType === 'NamedNode';
},
function isBlankNode(term) {
return !!term && term.termType === 'BlankNode';
} // Tests whether the given term represents a literal
// Tests whether the given term represents a blank node
isBlankNode: function (term) {
return !!term && term.termType === 'BlankNode';
},
// Tests whether the given term represents a literal
isLiteral: function (term) {
return !!term && term.termType === 'Literal';
},
function isLiteral(term) {
return !!term && term.termType === 'Literal';
} // Tests whether the given term represents a variable
// Tests whether the given term represents a variable
isVariable: function (term) {
return !!term && term.termType === 'Variable';
},
// Tests whether the given term represents the default graph
isDefaultGraph: function (term) {
return !!term && term.termType === 'DefaultGraph';
},
function isVariable(term) {
return !!term && term.termType === 'Variable';
} // Tests whether the given term represents the default graph
// Tests whether the given quad is in the default graph
inDefaultGraph: function (quad) {
return N3Util.isDefaultGraph(quad.graph);
},
// Creates a function that prepends the given IRI to a local name
prefix: function (iri, factory) {
return N3Util.prefixes({ '': iri }, factory)('');
},
function isDefaultGraph(term) {
return !!term && term.termType === 'DefaultGraph';
} // Tests whether the given quad is in the default graph
// Creates a function that allows registering and expanding prefixes
prefixes: function (defaultPrefixes, factory) {
// Add all of the default prefixes
var prefixes = Object.create(null);
for (var prefix in defaultPrefixes)
processPrefix(prefix, defaultPrefixes[prefix]);
// Set the default factory if none was specified
factory = factory || DataFactory;
// Registers a new prefix (if an IRI was specified)
// or retrieves a function that expands an existing prefix (if no IRI was specified)
function processPrefix(prefix, iri) {
// Create a new prefix if an IRI is specified or the prefix doesn't exist
if (typeof iri === 'string') {
// Create a function that expands the prefix
var cache = Object.create(null);
prefixes[prefix] = function (local) {
return cache[local] || (cache[local] = factory.namedNode(iri + local));
};
}
else if (!(prefix in prefixes)) {
throw new Error('Unknown prefix: ' + prefix);
}
return prefixes[prefix];
function inDefaultGraph(quad) {
return isDefaultGraph(quad.graph);
} // Creates a function that prepends the given IRI to a local name
function prefix(iri, factory) {
return prefixes({
'': iri
}, factory)('');
} // Creates a function that allows registering and expanding prefixes
function prefixes(defaultPrefixes, factory) {
// Add all of the default prefixes
var prefixes = Object.create(null);
for (var prefix in defaultPrefixes) processPrefix(prefix, defaultPrefixes[prefix]); // Set the default factory if none was specified
factory = factory || _N3DataFactory.default; // Registers a new prefix (if an IRI was specified)
// or retrieves a function that expands an existing prefix (if no IRI was specified)
function processPrefix(prefix, iri) {
// Create a new prefix if an IRI is specified or the prefix doesn't exist
if (typeof iri === 'string') {
// Create a function that expands the prefix
var cache = Object.create(null);
prefixes[prefix] = function (local) {
return cache[local] || (cache[local] = factory.namedNode(iri + local));
};
} else if (!(prefix in prefixes)) {
throw new Error('Unknown prefix: ' + prefix);
}
return processPrefix;
},
};
// ## Exports
module.exports = N3Util;
return prefixes[prefix];
}
return processPrefix;
}

@@ -1,21 +0,35 @@

// **N3Writer** writes N3 documents.
"use strict";
var namespaces = require('./IRIs'),
DataFactory = require('./N3DataFactory');
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var DEFAULTGRAPH = DataFactory.defaultGraph();
var _IRIs = _interopRequireDefault(require("./IRIs"));
var rdf = namespaces.rdf,
xsd = namespaces.xsd;
var _N3DataFactory = _interopRequireDefault(require("./N3DataFactory"));
// Characters in literals that require escaping
var escape = /["\\\t\n\r\b\f\u0000-\u0019\ud800-\udbff]/,
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// **N3Writer** writes N3 documents.
const DEFAULTGRAPH = _N3DataFactory.default.defaultGraph();
const {
rdf,
xsd
} = _IRIs.default; // Characters in literals that require escaping
var escape = /["\\\t\n\r\b\f\u0000-\u0019\ud800-\udbff]/,
escapeAll = /["\\\t\n\r\b\f\u0000-\u0019]|[\ud800-\udbff][\udc00-\udfff]/g,
escapedCharacters = {
'\\': '\\\\', '"': '\\"', '\t': '\\t',
'\n': '\\n', '\r': '\\r', '\b': '\\b', '\f': '\\f',
};
'\\': '\\\\',
'"': '\\"',
'\t': '\\t',
'\n': '\\n',
'\r': '\\r',
'\b': '\\b',
'\f': '\\f'
}; // ## Placeholder class to represent already pretty-printed terms
// ## Placeholder class to represent already pretty-printed terms
class SerializedTerm extends DataFactory.internal.Term {
class SerializedTerm extends _N3DataFactory.default.internal.Term {
// Pretty-printed nodes are not equal to any other node

@@ -26,54 +40,56 @@ // (e.g., [] does not equal [])

}
}
// ## Constructor
} // ## Constructor
class N3Writer {
constructor(outputStream, options) {
// ### `_prefixRegex` matches a prefixed name or IRI that begins with one of the added prefixes
this._prefixRegex = /$0^/;
this._prefixRegex = /$0^/; // Shift arguments if the first argument is not a stream
// Shift arguments if the first argument is not a stream
if (outputStream && typeof outputStream.write !== 'function')
options = outputStream, outputStream = null;
options = options || {};
if (outputStream && typeof outputStream.write !== 'function') options = outputStream, outputStream = null;
options = options || {}; // If no output stream given, send the output as string through the end callback
// If no output stream given, send the output as string through the end callback
if (!outputStream) {
var output = '';
this._outputStream = {
write(chunk, encoding, done) { output += chunk; done && done(); },
end: function (done) { done && done(null, output); },
write(chunk, encoding, done) {
output += chunk;
done && done();
},
end: function (done) {
done && done(null, output);
}
};
this._endStream = true;
}
else {
} else {
this._outputStream = outputStream;
this._endStream = options.end === undefined ? true : !!options.end;
}
} // Initialize writer, depending on the format
// Initialize writer, depending on the format
this._subject = null;
if (!(/triple|quad/i).test(options.format)) {
if (!/triple|quad/i.test(options.format)) {
this._graph = DEFAULTGRAPH;
this._prefixIRIs = Object.create(null);
options.prefixes && this.addPrefixes(options.prefixes);
}
else {
} else {
this._writeQuad = this._writeQuadLine;
}
}
} // ## Private methods
// ### Whether the current graph is the default graph
// ## Private methods
// ### Whether the current graph is the default graph
get _inDefaultGraph() {
return DEFAULTGRAPH.equals(this._graph);
}
} // ### `_write` writes the argument to the output stream
// ### `_write` writes the argument to the output stream
_write(string, callback) {
this._outputStream.write(string, 'utf8', callback);
}
} // ### `_writeQuad` writes the quad to the output stream
// ### `_writeQuad` writes the quad to the output stream
_writeQuad(subject, predicate, object, graph, done) {

@@ -84,44 +100,34 @@ try {

// Close the previous graph and start the new one
this._write((this._subject === null ? '' : (this._inDefaultGraph ? '.\n' : '\n}\n')) +
(DEFAULTGRAPH.equals(graph) ? '' : this._encodeIriOrBlank(graph) + ' {\n'));
this._write((this._subject === null ? '' : this._inDefaultGraph ? '.\n' : '\n}\n') + (DEFAULTGRAPH.equals(graph) ? '' : this._encodeIriOrBlank(graph) + ' {\n'));
this._graph = graph;
this._subject = null;
}
// Don't repeat the subject if it's the same
} // Don't repeat the subject if it's the same
if (subject.equals(this._subject)) {
// Don't repeat the predicate if it's the same
if (predicate.equals(this._predicate))
this._write(', ' + this._encodeObject(object), done);
// Same subject, different predicate
else
this._write(';\n ' +
this._encodePredicate(this._predicate = predicate) + ' ' +
this._encodeObject(object), done);
}
// Different subject; write the whole quad
else
this._write((this._subject === null ? '' : '.\n') +
this._encodeIriOrBlank(this._subject = subject) + ' ' +
this._encodePredicate(this._predicate = predicate) + ' ' +
this._encodeObject(object), done);
if (predicate.equals(this._predicate)) this._write(', ' + this._encodeObject(object), done); // Same subject, different predicate
else this._write(';\n ' + this._encodePredicate(this._predicate = predicate) + ' ' + this._encodeObject(object), done);
} // Different subject; write the whole quad
else this._write((this._subject === null ? '' : '.\n') + this._encodeIriOrBlank(this._subject = subject) + ' ' + this._encodePredicate(this._predicate = predicate) + ' ' + this._encodeObject(object), done);
} catch (error) {
done && done(error);
}
catch (error) { done && done(error); }
}
} // ### `_writeQuadLine` writes the quad to the output stream as a single line
// ### `_writeQuadLine` writes the quad to the output stream as a single line
_writeQuadLine(subject, predicate, object, graph, done) {
// Write the quad without prefixes
delete this._prefixMatch;
this._write(this.quadToString(subject, predicate, object, graph), done);
}
} // ### `quadToString` serializes a quad as a string
// ### `quadToString` serializes a quad as a string
quadToString(subject, predicate, object, graph) {
return this._encodeIriOrBlank(subject) + ' ' +
this._encodeIriOrBlank(predicate) + ' ' +
this._encodeObject(object) +
(graph && graph.value ? ' ' + this._encodeIriOrBlank(graph) + ' .\n' : ' .\n');
}
return this._encodeIriOrBlank(subject) + ' ' + this._encodeIriOrBlank(predicate) + ' ' + this._encodeObject(object) + (graph && graph.value ? ' ' + this._encodeIriOrBlank(graph) + ' .\n' : ' .\n');
} // ### `quadsToString` serializes an array of quads as a string
// ### `quadsToString` serializes an array of quads as a string
quadsToString(quads) {

@@ -131,69 +137,55 @@ return quads.map(function (t) {

}, this).join('');
}
} // ### `_encodeIriOrBlank` represents an IRI or blank node
// ### `_encodeIriOrBlank` represents an IRI or blank node
_encodeIriOrBlank(entity) {
// A blank node or list is represented as-is
if (entity.termType !== 'NamedNode')
return 'id' in entity ? entity.id : '_:' + entity.value;
// Escape special characters
if (entity.termType !== 'NamedNode') return 'id' in entity ? entity.id : '_:' + entity.value; // Escape special characters
var iri = entity.value;
if (escape.test(iri))
iri = iri.replace(escapeAll, characterReplacer);
// Try to represent the IRI as prefixed name
if (escape.test(iri)) iri = iri.replace(escapeAll, characterReplacer); // Try to represent the IRI as prefixed name
var prefixMatch = this._prefixRegex.exec(iri);
return !prefixMatch ? '<' + iri + '>' :
(!prefixMatch[1] ? iri : this._prefixIRIs[prefixMatch[1]] + prefixMatch[2]);
}
// ### `_encodeLiteral` represents a literal
return !prefixMatch ? '<' + iri + '>' : !prefixMatch[1] ? iri : this._prefixIRIs[prefixMatch[1]] + prefixMatch[2];
} // ### `_encodeLiteral` represents a literal
_encodeLiteral(literal) {
// Escape special characters
var value = literal.value;
if (escape.test(value))
value = value.replace(escapeAll, characterReplacer);
// Write the literal, possibly with type or language
if (literal.language)
return '"' + value + '"@' + literal.language;
else if (literal.datatype.value !== xsd.string)
return '"' + value + '"^^' + this._encodeIriOrBlank(literal.datatype);
else
return '"' + value + '"';
}
if (escape.test(value)) value = value.replace(escapeAll, characterReplacer); // Write the literal, possibly with type or language
// ### `_encodePredicate` represents a predicate
if (literal.language) return '"' + value + '"@' + literal.language;else if (literal.datatype.value !== xsd.string) return '"' + value + '"^^' + this._encodeIriOrBlank(literal.datatype);else return '"' + value + '"';
} // ### `_encodePredicate` represents a predicate
_encodePredicate(predicate) {
return predicate.value === rdf.type ? 'a' : this._encodeIriOrBlank(predicate);
}
} // ### `_encodeObject` represents an object
// ### `_encodeObject` represents an object
_encodeObject(object) {
return object.termType === 'Literal' ? this._encodeLiteral(object) : this._encodeIriOrBlank(object);
}
} // ### `_blockedWrite` replaces `_write` after the writer has been closed
// ### `_blockedWrite` replaces `_write` after the writer has been closed
_blockedWrite() {
throw new Error('Cannot write because the writer has been closed.');
}
} // ### `addQuad` adds the quad to the output stream
// ### `addQuad` adds the quad to the output stream
addQuad(subject, predicate, object, graph, done) {
// The quad was given as an object, so shift parameters
if (object === undefined)
this._writeQuad(subject.subject, subject.predicate, subject.object, subject.graph, predicate);
// The optional `graph` parameter was not provided
else if (typeof graph === 'function')
this._writeQuad(subject, predicate, object, DEFAULTGRAPH, graph);
// The `graph` parameter was provided
else
this._writeQuad(subject, predicate, object, graph || DEFAULTGRAPH, done);
}
if (object === undefined) this._writeQuad(subject.subject, subject.predicate, subject.object, subject.graph, predicate); // The optional `graph` parameter was not provided
else if (typeof graph === 'function') this._writeQuad(subject, predicate, object, DEFAULTGRAPH, graph); // The `graph` parameter was provided
else this._writeQuad(subject, predicate, object, graph || DEFAULTGRAPH, done);
} // ### `addQuads` adds the quads to the output stream
// ### `addQuads` adds the quads to the output stream
addQuads(quads) {
for (var i = 0; i < quads.length; i++)
this.addQuad(quads[i]);
}
for (var i = 0; i < quads.length; i++) this.addQuad(quads[i]);
} // ### `addPrefix` adds the prefix to the output stream
// ### `addPrefix` adds the prefix to the output stream
addPrefix(prefix, iri, done) {

@@ -203,28 +195,35 @@ var prefixes = {};

this.addPrefixes(prefixes, done);
}
} // ### `addPrefixes` adds the prefixes to the output stream
// ### `addPrefixes` adds the prefixes to the output stream
addPrefixes(prefixes, done) {
// Add all useful prefixes
var prefixIRIs = this._prefixIRIs, hasPrefixes = false;
var prefixIRIs = this._prefixIRIs,
hasPrefixes = false;
for (var prefix in prefixes) {
// Verify whether the prefix can be used and does not exist yet
var iri = prefixes[prefix];
if (typeof iri !== 'string')
iri = iri.value;
if (typeof iri !== 'string') iri = iri.value;
if (/[#\/]$/.test(iri) && prefixIRIs[iri] !== (prefix += ':')) {
hasPrefixes = true;
prefixIRIs[iri] = prefix;
// Finish a possible pending quad
prefixIRIs[iri] = prefix; // Finish a possible pending quad
if (this._subject !== null) {
this._write(this._inDefaultGraph ? '.\n' : '\n}\n');
this._subject = null, this._graph = '';
}
// Write prefix
} // Write prefix
this._write('@prefix ' + prefix + ' <' + iri + '>.\n');
}
}
// Recreate the prefix matcher
} // Recreate the prefix matcher
if (hasPrefixes) {
var IRIlist = '', prefixList = '';
var IRIlist = '',
prefixList = '';
for (var prefixIRI in prefixIRIs) {

@@ -234,63 +233,63 @@ IRIlist += IRIlist ? '|' + prefixIRI : prefixIRI;

}
IRIlist = IRIlist.replace(/[\]\/\(\)\*\+\?\.\\\$]/g, '\\$&');
this._prefixRegex = new RegExp('^(?:' + prefixList + ')[^\/]*$|' +
'^(' + IRIlist + ')([a-zA-Z][\\-_a-zA-Z0-9]*)$');
}
// End a prefix block with a newline
this._prefixRegex = new RegExp('^(?:' + prefixList + ')[^\/]*$|' + '^(' + IRIlist + ')([a-zA-Z][\\-_a-zA-Z0-9]*)$');
} // End a prefix block with a newline
this._write(hasPrefixes ? '\n' : '', done);
}
} // ### `blank` creates a blank node with the given content
// ### `blank` creates a blank node with the given content
blank(predicate, object) {
var children = predicate, child, length;
// Empty blank node
if (predicate === undefined)
children = [];
// Blank node passed as blank(Term("predicate"), Term("object"))
else if (predicate.termType)
children = [{ predicate: predicate, object: object }];
// Blank node passed as blank({ predicate: predicate, object: object })
else if (!('length' in predicate))
children = [predicate];
var children = predicate,
child,
length; // Empty blank node
if (predicate === undefined) children = []; // Blank node passed as blank(Term("predicate"), Term("object"))
else if (predicate.termType) children = [{
predicate: predicate,
object: object
}]; // Blank node passed as blank({ predicate: predicate, object: object })
else if (!('length' in predicate)) children = [predicate];
switch (length = children.length) {
// Generate an empty blank node
case 0:
return new SerializedTerm('[]');
// Generate a non-nested one-triple blank node
case 1:
child = children[0];
if (!(child.object instanceof SerializedTerm))
return new SerializedTerm('[ ' + this._encodePredicate(child.predicate) + ' ' +
this._encodeObject(child.object) + ' ]');
// Generate a multi-triple or nested blank node
default:
var contents = '[';
// Write all triples in order
for (var i = 0; i < length; i++) {
child = children[i];
// Write only the object is the predicate is the same as the previous
if (child.predicate.equals(predicate))
contents += ', ' + this._encodeObject(child.object);
// Otherwise, write the predicate and the object
else {
contents += (i ? ';\n ' : '\n ') +
this._encodePredicate(child.predicate) + ' ' +
this._encodeObject(child.object);
predicate = child.predicate;
// Generate an empty blank node
case 0:
return new SerializedTerm('[]');
// Generate a non-nested one-triple blank node
case 1:
child = children[0];
if (!(child.object instanceof SerializedTerm)) return new SerializedTerm('[ ' + this._encodePredicate(child.predicate) + ' ' + this._encodeObject(child.object) + ' ]');
// Generate a multi-triple or nested blank node
default:
var contents = '['; // Write all triples in order
for (var i = 0; i < length; i++) {
child = children[i]; // Write only the object is the predicate is the same as the previous
if (child.predicate.equals(predicate)) contents += ', ' + this._encodeObject(child.object); // Otherwise, write the predicate and the object
else {
contents += (i ? ';\n ' : '\n ') + this._encodePredicate(child.predicate) + ' ' + this._encodeObject(child.object);
predicate = child.predicate;
}
}
}
return new SerializedTerm(contents + '\n]');
return new SerializedTerm(contents + '\n]');
}
}
} // ### `list` creates a list node with the given content
// ### `list` creates a list node with the given content
list(elements) {
var length = elements && elements.length || 0, contents = new Array(length);
for (var i = 0; i < length; i++)
contents[i] = this._encodeObject(elements[i]);
var length = elements && elements.length || 0,
contents = new Array(length);
for (var i = 0; i < length; i++) contents[i] = this._encodeObject(elements[i]);
return new SerializedTerm('(' + contents.join(' ') + ')');
}
} // ### `end` signals the end of the output stream
// ### `end` signals the end of the output stream
end(done) {

@@ -300,21 +299,33 @@ // Finish a possible pending quad

this._write(this._inDefaultGraph ? '.\n' : '\n}\n');
this._subject = null;
}
// Disallow further writing
this._write = this._blockedWrite;
} // Disallow further writing
// Try to end the underlying stream, ensuring done is called exactly one time
var singleDone = done && function (error, result) { singleDone = null, done(error, result); };
this._write = this._blockedWrite; // Try to end the underlying stream, ensuring done is called exactly one time
var singleDone = done && function (error, result) {
singleDone = null, done(error, result);
};
if (this._endStream) {
try { return this._outputStream.end(singleDone); }
catch (error) { /* error closing stream */ }
try {
return this._outputStream.end(singleDone);
} catch (error) {
/* error closing stream */
}
}
singleDone && singleDone();
}
}
// Replaces a character by its escaped version
} // Replaces a character by its escaped version
exports.default = N3Writer;
function characterReplacer(character) {
// Replace a single character by its escaped version
var result = escapedCharacters[character];
if (result === undefined) {

@@ -325,14 +336,10 @@ // Replace a single character with its 4-bit unicode escape sequence

result = '\\u0000'.substr(0, 6 - result.length) + result;
}
// Replace a surrogate pair with its 8-bit unicode escape sequence
} // Replace a surrogate pair with its 8-bit unicode escape sequence
else {
result = ((character.charCodeAt(0) - 0xD800) * 0x400 +
character.charCodeAt(1) + 0x2400).toString(16);
result = '\\U00000000'.substr(0, 10 - result.length) + result;
}
result = ((character.charCodeAt(0) - 0xD800) * 0x400 + character.charCodeAt(1) + 0x2400).toString(16);
result = '\\U00000000'.substr(0, 10 - result.length) + result;
}
}
return result;
}
// ## Exports
module.exports = N3Writer;
}
{
"name": "n3",
"version": "1.1.1",
"version": "1.2.0",
"description": "Lightning fast, asynchronous, streaming Turtle / N3 / RDF library.",

@@ -14,3 +14,5 @@ "author": "Ruben Verborgh <ruben.verborgh@gmail.com>",

"license": "MIT",
"main": "./N3.js",
"main": "./lib/index.js",
"module": "./src/index.js",
"sideEffects": false,
"engines": {

@@ -20,6 +22,11 @@ "node": ">=8.0"

"files": [
"N3.js",
".babelrc",
"src",
"lib"
],
"devDependencies": {
"@babel/cli": "^7.5.5",
"@babel/core": "^7.5.5",
"@babel/preset-env": "^7.5.5",
"@babel/register": "^7.5.5",
"arrayify-stream": "^1.0.0",

@@ -32,3 +39,3 @@ "chai": "^4.0.2",

"mocha": "^5.0.1",
"nyc": "^13.3.0",
"nyc": "^14.1.1",
"pre-commit": "^1.2.2",

@@ -39,4 +46,6 @@ "rdf-test-suite": "^1.2.0",

"scripts": {
"test": "nyc mocha",
"lint": "eslint lib perf test spec",
"build": "babel src -d lib",
"test": "nyc mocha --require @babel/register",
"lint": "eslint src perf test spec",
"prepare": "npm run build",
"spec": "npm run spec-turtle && npm run spec-ntriples && npm run spec-nquads && npm run spec-trig",

@@ -53,3 +62,3 @@ "spec-earl": "npm run spec-earl-turtle && npm run spec-earl-ntriples && npm run spec-earl-nquads && npm run spec-earl-trig",

"spec-clean": "rm -r .rdf-test-suite-cache/",
"docs": "docco lib/*.js"
"docs": "docco src/*.js"
},

@@ -56,0 +65,0 @@ "repository": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc