A collection of RDF libraries for JavaScript
@graphy/core.data.factory
factory is used throughout this document to refer to this module’s export.typeof value === 'object' && value.constructor === ObjectThe following code block demonstrates three different ways to access this module.
// stand-alone
const factory = require('@graphy/core.data.factory');
// via the graphy 'super module'
const graphy = require('graphy');
const factory = graphy.core.data.factory;
// via inheritted methods on the graphy 'super module'
const graphy = require('graphy');
const factory = graphy;
The following section describes hinted formatting on ES primitives that are used throughout this document.
#number/integer – any number such that Numer.isInteger(value) === true.#number/double – any number.#string/term-verbose – a string which is conformant with the grammar production subject, predicate, object or graphLabel as they are defined in the N-Triples and N-Quads specifications.#string/quad-verbose – a string which is conformant with the grammar production statement as is is defined in the N-Quads specification.#string/term-terse – a string which is conformant with the grammar production IRIREF, RDFLiteral, or PrefixedName as they are defined in the Turtle specification.A ‘struct’ refers to an interface for a simple ES Object value such that value.constructor === Object. This is important because some methods may perform duck-typing on their arguments in order to deduce which overloaded variant to employ. The following section documents the definitions for these interfaces.
#struct/term-isolate – an object that represents an isolated RDF term.
.termType: string.value: string.datatype: #struct/term-isolate.language: #string/language-tag#struct/quad-isolate – an object that represents an isolated RDF quad.
.subject : #struct/term-isolate.predicate : #struct/term-isolate.object : #struct/term-isolate.graph : #struct/term-isolateA ‘hash’ is a synonym of a HashMap; it refers to an object whose keys are arbitrarily decided by you, the user. The following section documents significance of the keys and expected values for hashes used by this library.
#hash/prefix-mappings – an object that represents the mappings from a prefix string to its expanded IRI.
interface **PrefixMappings** { [prefix: string]: string; };
factory.namedNode(iri: string) factory.namedNode('http://ex.org/test').verbose(); // '<http://ex.org/test>'
factory.blankNode(...)() – ‘auto’-version (no args constructor) will generate a new UUID4 in attempt to avoid label collisions(label: string) – uses the given label // no-args constructor
factory.blankNode().verbose(); // '_:_439e14ae_1531_4683_ac96_b9f091da9595'
// use given label constructor
factory.blankNode('label').verbose(); // '_:label'
factory.defaultGraph() graphy.defaultGraph().verbose(); // ''
graphy.defaultGraph().termType; // 'DefaultGraph'
factory.literal(contents: string[, datatype_or_lang: NamedNode | #string/language-tag])datatype_or_lang factory.literal('"').verbose(); // '"\""^^<http://www.w3.org/2001/XMLSchema#string>'
factory.literal('42', 'http://ex.org/datatype').verbose(); // '"42"@http://ex.org/datatype'
factory.literal('hello Mars!', 'en').verbose(); // '"hello Mars!"@en'
// for backwards-compatibility, the '@' character is also allowed in the language tag argument version
factory.literal('hello Mars!', '@en').verbose(); // '"hello Mars!"@en'
factory.ephemeral() let kt_ephemeral = factory.ephemeral();
kt_ephemeral.isAnonymous; // true
kt_ephemeral.isEphemeral; // true
// returns a different label each time `.value` is accessed to ensure it is not accidentally reused
kt_ephemeral.value; // '_66f0cc19_e551_4d82_8bf2_73329fb578b2'
kt_ephemeral.value; // '_12ebb618_981b_45c9_a63b_a1e30170fcd1'
kt_ephemeral.value; // '_4335c2d1_b7e2_4a43_ae81_a9f3a73e31ab'
// same thing happens with `.verbose()` string
kt_ephemeral.verbose(); // '_:_82d116e8_352b_4ec3_8e3a_3b100a53b557'
kt_ephemeral.verbose(); // '_:_72b4a5ab_f4f0_494c_a432_c82b9d5aed50'
kt_ephemeral.verbose(); // '_:_1110a7e0_39fa_45ed_88c3_03912da0d93c'
// the `.terse()` string is the anonymous blank node token!
kt_ephemeral.terse(); // '[]'
// will never equal itself
kt_ephemeral.equals(kt_ephemeral); // false
// demonstration being used in c3/c4 hashes
[...factory.c3({
// create a non-reusable blank node as the subject of some triples
[factory.ephemeral()]: {
a: 'owl:Thing',
'demo:refs': factory.ephemeral(),
},
}, h_prefixes)].map(g => g.terse()).join(''); // '[] a owl:Thing; demo:refs [] .'
factory.boolean(value: boolean | number | string)value is a number, it must be either 1 or 0. If value is a string, it must match /^([Tt](rue)?|TRUE)$/ or /^([Ff](alse)?|FALSE)$/.factory.integer(value: #number/integer | string)factory.double(value: number | string)factory.decimal(value: number | string)factory.number(value: number)value is an integer or not. Otherwise, if value is infinite or NaN, will return an RDF literal with an XSD double datatype.value. const h_prefixes = {xsd:'http://www.w3.org/2001/XMLSchema#'};
factory.number(42).datatype.terse(h_prefixes); // 'xsd:integer'
factory.number(Math.PI).datatype.terse(h_prefixes); // 'xsd:decimal'
factory.number(Infinity).datatype.terse(h_prefixes); // 'xsd:double'
factory.date(date: Date) const h_prefixes = {xsd:'http://www.w3.org/2001/XMLSchema#'};
let dt_event = new Date('December 17, 1995 03:24:00');
factory.date(dt_event).terse(h_prefixes); // '"1995-12-17Z"^^xsd:date'
factory.dateTime(dateTime: Date) const h_prefixes = {xsd:'http://www.w3.org/2001/XMLSchema#'};
let dt_event = new Date('December 17, 1995 03:24:00');
factory.dateTime(dt_event).terse(h_prefixes); // '"1995-12-17T11:24:00.000Z"^^xsd:dateTime'
factory.quad(subject: Term, predicate: Term, object: Term, graph: Term) let kt_banana = factory.namedNode('http://ex.org/Banana');
let kt_color = factory.namedNode('http://ex.org/color');
let kt_yellow = factory.literal('yellow', factory.namedNode('http://ex.org/Color'));
let kt_graph = factory.namedNode('http://ex.org/graph');
factory.quad(kt_banana, kt_color, kt_yellow, kt_graph).terse({ex:'http://ex.org/'}); // ex:graph { ex:Banana ex:color "yellow" . }
// recommended way using `factory.c4`
[...factory.c4({
'ex:graph': {
'ex:Banana': {
'ex:color': 'ex:Color^"yellow',
},
},
}, {ex:'http://ex.org/'})].map(k_quad => k_quad.terse({ex:'http://ex.org/'})); // ['ex:graph { ex:Banana ex:color <http://ex.org/Color\u005e\u0022yellow> . }']
factory.c1(term: #string/concise-term[, prefixes: #hash/prefix-mappings])*factory.c3(triples: #hash/concise-triples[, prefixes: #hash/prefix-mappings])*factory.c4(quads: #hash/concise-quads[, prefixes: #hash/prefix-mappings])factory.fromTerm(term: AnyTerm) factory.fromTerm({
termType: 'NamedNode',
value: 'z://a',
}).verbose(); // '<z://a>'
factory.fromQuad(term: AnyQuad) factory.fromQuad({
subject: {
termType: 'NamedNode',
value: 'z://y/a',
},
predicate: {
termType: 'NamedNode',
value: 'z://y/b',
},
object: {
termType: 'NamedNode',
value: 'z://y/c',
},
// optional
graph: {
termType: 'NamedNode',
value: 'z://y/g',
},
}).verbose(); // '<z://y/a> <z://y/b> <z://y/c> <z://y/g> .'
factory.comment(config: #config/comment)#string/concise-term // snippets/write-comment.js
const factory = require('@graphy/core.data.factory');
const ttl_write = require('@graphy/content.ttl.write');
let ds_writer = ttl_write({
prefixes: {
demo: 'http://ex.org/',
dbo: 'http://dbpedia.org/ontology/',
rdfs: 'http://www.w3.org/2000/01/rdf-schema#',
rdf: 'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
},
});
ds_writer.pipe(process.stdout);
ds_writer.write({
type: 'c3',
value: {
[factory.comment()]: 'this is a comment',
'demo:Banana': {
a: 'dbo:Fruit',
[factory.comment()]: 'so is this...',
'rdfs:label': '@en"Banana',
},
},
});
ds_writer.end();
@prefix demo: <http://ex.org/> .
@prefix dbo: <http://dbpedia.org/ontology/> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
# this is a comment
demo:Banana a dbo:Fruit ;
# so is this...
rdfs:label "Banana"@en .
Properties:
.isGraphyTerm : boolean = trueMethods:
equals(other: AnyTerm)
booleanverbose()
#string/term_verboseterse(prefix_map: #hash/prefix-mappings)
#string/term_terseconcise(prefix_map: #hash/prefix-mappings)
#string/term_conciseisolate() – creates a self-contained object representation of this term, devoid of references to other objects
#struct/term-isolate factory.namedNode('http://ex.org/test').isolate(); // {termType:'NamedNode', value:'http://ex.org/test'}
factory.blankNode('yellow').isolate(); // {termType:'BlankNode', value:'yellow'}
factory.integer(42).isolate(); /* {
termType: 'Literal',
value: '42',
datatype: {
termType: 'NamedNode',
value: 'http://www.w3.org/2001/XMLSchema#integer',
},
} */
A class that represents an RDF named node.
Properties implementing @RDFJS/NamedNode:
.termType : string = 'NamedNode'.value : string – the IRI of this named nodeProperties:
.isNamedNode : boolean = true – a faster alternative to test for NamedNode term typesMethods:
A class that represents an RDF blank node.
Properties implementing @RDFJS/BlankNode:
.termType : string = 'BlankNode'.value : string – the label of this blank node (i.e., without leading '_:')Properties:
.isBlankNode : boolean = true – a faster alternative to test for BlankNode term types.isAnonymous : boolean – whether or not this term was constructed from an anonymous blank nodeMethods:
Examples:
let kt_auto = factory.blankNode();
let kt_labeled = factory.blankNode('label');
kt_auto.isAnonymous; // false
kt_label.isAnonymous; // false
kt_auto.value; // '_f4b39957_4619_459e_b954_a26f7b6da4a'
kt_label.value; // 'label'
graphy.content.ttl.read('_:a <b> [] .', {
data(y_quad) {
y_quad.subject.isAnonymous; // false
y_quad.object.isAnonymous; // true
},
});
A class that represents an anonymous RDF blank node with ephemeral qualities. Primarily used for writing.
Properties implementing @RDFJS/BlankNode:
.termType : string = 'BlankNode'.value : string – the label of a blank node (i.e., without leading '_:') which changes everytime it is accessedProperties:
.isAnonymous : boolean = true – indicates this represents an anonymous blank node.isEphemeral : boolean = true – used to help indicate to interested parties that this blank node is ephemeralMethods:
equals(other: AnyTerm)
.equals() any other term no matter whatfalseExamples:
let kt_ephemeral = factory.ephemeral();
kt_ephemeral.isAnonymous; // true
kt_ephemeral.isEphemeral; // true
// changes everytime it is accessed
kt_ephemeral.value; // '_66f0cc19_e551_4d82_8bf2_73329fb578b2'
kt_ephemeral.value; // '_12ebb618_981b_45c9_a63b_a1e30170fcd1'
kt_ephemeral.value; // '_4335c2d1_b7e2_4a43_ae81_a9f3a73e31ab'
// same applies to the verbose string
kt_ephemeral.verbose(); // '_:_82d116e8_352b_4ec3_8e3a_3b100a53b557'
kt_ephemeral.verbose(); // '_:_72b4a5ab_f4f0_494c_a432_c82b9d5aed50'
kt_ephemeral.verbose(); // '_:_1110a7e0_39fa_45ed_88c3_03912da0d93c'
// the terse string is the anonymous blank node token
kt_ephemeral.terse(); // '[]'
// will never equal itself
kt_ephemeral.equals(kt_ephemeral); // false
A class that represents an RDF default graph.
Properties implementing @RDFJS/DefaultGraph:
.termType : string = 'DefaultGraph'.value : string = '' (an empty string)Properties:
.isDefaultGraph : boolean = true – a faster alternative to test for DefaultGraph term typesMethods:
A class that represents an RDF literal.
Properties implementing @RDFJS/Literal:
.termType : string = 'Literal'.value : string – the contents of this literal.datatype : NamedNode – the datatype of this literal (defaults to rdf:langString).language : #string/language-tag – the language tag associated with this literal (will be an empty string if it has no language)Properties:
.isLiteral : boolean = true – a faster alternative to test for Literal term types.isSimple : boolean – whether or not this Literal is ‘simple’, i.e., it has the datatype xsd:string and no language tag..isLanguaged : boolean – whether or not this Literal is ‘languaged’, i.e., it has some language tag and the datatype rdf:langString..isDatatyped : boolean – whether or not this Literal is ‘datatyped’, i.e., it has some datatype other than xsd:string and no language tag.Methods:
A class that represents an RDF literal that is an xsd:boolean.
Properties:
.isBoolean : boolean = true – indicates that this object has a boolean value (i.e., typeof this.number === 'boolean')..boolean : boolean - the boolean value of this RDF literal.Methods:
Examples:
let kt_true = factory.boolean(true);
kt_true = factory.boolean(1);
kt_true = factory.boolean('t');
kt_true = factory.boolean('true');
kt_true = factory.boolean('True');
kt_true = factory.boolean('TRUE');
let kt_false = factory.boolean(false);
kt_false = factory.boolean(0);
kt_false = factory.boolean('f');
kt_false = factory.boolean('false');
kt_false = factory.boolean('False');
kt_false = factory.boolean('FALSE');
kt_true.isolate(); // {termType:'Literal', value:'true', language:'', datatype:{termType:'NamedNode', value:'http://www.w3.org/2001/XMLSchema#boolean', }, }
kt_true.verbose(); // "true"^^<http://www.w3.org/2001/XMLSchema#boolean>
kt_true.terse(); // true
kt_true.isBoolean; // true
kt_true.boolean; // true
kt_true.value; // true
A class that represents an RDF literal that is an xsd:integer.
Properties:
.isNumeric : boolean = true – indicates that this object has a numeric value (i.e., typeof this.number === 'number')..isInteger : boolean = true – indicates that this object has an integer value (i.e., Number.isInteger(this.number) === true)..number : #number/integer - the numeric integer value of this RDF literal.Methods:
Examples:
let yt_answer = factory.integer(42);
yt_answer.verbose(); // '"42"^^<http://www.w3.org/2001/XMLSchema#integer>'
yt_answer.isNumeric; // true
yt_answer.isInteger; // true
yt_answer.isDouble; // undefined
yt_answer.number + 1; // 43
yt_answer.value; // '42'
factory.integer('12').number; // 12
factory.integer(12.1); // throws an Error: Number is not an integer: 12.1
factory.integer('12.1'); // throws an Error: Invalid integer string: 12.1
A class that represents an RDF literal that is an xsd:decimal.
Properties:
.isNumeric : boolean = true – indicates that this object has a numeric value (i.e., typeof this.number === 'number')..isDecimal : boolean = true – indicates that this object has a decimal value (note that decimals can never encode +/- infinity nor NaN)..number : #number/double - the numeric double value of this RDF literal.Methods:
A class that represents an RDF literal that is an xsd:double.
Properties:
.isNumeric : boolean = true – indicates that this object has a numeric value (i.e., typeof this.number === 'number')..isDouble : boolean = true – indicates that this object has a double value, which may include +Infinity, -Infinity or NaN..number : #number/double - the numeric double value of this RDF literal.Methods:
Examples:
let yt_pi = factory.double(Math.PI);
yt_pi.value; // '3.141592653589793'
yt_pi.isolate(); // '{termType:'Literal', value:'3.141592653589793', language:'', datatype:{termType:'NamedNode', value:'http://www.w3.org/2001/XMLSchema#double', }, }'
yt_pi.verbose(); // '"3.141592653589793"^^<http://www.w3.org/2001/XMLSchema#double>'
yt_pi.terse(); // '"3.141592653589793"^^<http://www.w3.org/2001/XMLSchema#double>'
yt_pi.isNumeric; // true
yt_pi.isDouble; // true
yt_pi.isInteger; // undefined
yt_pi.number * 2; // 6.283185307179586
graphy.content.ttl.read('<http://ex.org/unit-circle> <http://ex.org/area> 3.141592653589793 .', {
data(y_quad) {
y_quad.object.value; // '3.141592653589793'
y_quad.object.number; // 3.141592653589793
y_quad.object.datatype.value; // 'http://www.w3.org/2001/XMLSchema#double'
},
});
A class that represents an RDF literal that is positive infinity, which is of type xsd:double.
Overriding properties:
.value : string = 'INF' – the XSD-comformant string representation of this double..number : number = Infinity - the numeric positive infinity value of this RDF literal.Properties:
.isInfinite : boolean = true – indicates that this object has an infinite numeric value (i.e., Number.isFinite(this.number) === false)Methods:
Examples:
let yt_pos_inf = factory.double(Infinity);
yt_pos_inf.value; // INF
yt_pos_inf.isolate(); // '{termType:'Literal', value:'INF', language:'', datatype:{termType:'NamedNode', value:'http://www.w3.org/2001/XMLSchema#double', }, }'
yt_pos_inf.verbose(); // '"INF"^^<http://www.w3.org/2001/XMLSchema#double>'
yt_pos_inf.terse(); // '"INF"^^<http://www.w3.org/2001/XMLSchema#double>'
yt_pos_inf.isNumeric; // true
yt_pos_inf.isDouble; // true
yt_pos_inf.isInfinite; // true
yt_pos_inf.number; // Infinity
A class that represents an RDF literal that is negative infinity, which is of type xsd:double.
Overriding properties:
.value : string = '-INF' – the XSD-comformant string representation of this double..number : number = -Infinity - the numeric negative infinity value of this RDF literal.Properties:
.isInfinite : boolean = true – indicates that this object has an infinite numeric value (i.e., Number.isFinite(this.number) === false)Methods:
Examples:
let yt_neg_inf = factory.double(-Infinity);
yt_neg_inf.value; // -INF
yt_neg_inf.isolate(); // '{termType:'Literal', value:'-INF', language:'', datatype:{termType:'NamedNode', value:'http://www.w3.org/2001/XMLSchema#double', }, }'
yt_neg_inf.verbose(); // '"-INF"^^<http://www.w3.org/2001/XMLSchema#double>'
yt_neg_inf.terse(); // '"-INF"^^<http://www.w3.org/2001/XMLSchema#double>'
yt_neg_inf.isNumeric; // true
yt_neg_inf.isDouble; // true
yt_neg_inf.isInfinite; // true
yt_neg_inf.number; // -Infinity
A class that represents an RDF literal that is NaN, which is of type xsd:double.
Overriding properties:
.value : string = 'NaN' – the XSD-comformant string representation of this double..number : number = NaN - the numeric NaN value of this RDF literal.Properties:
.isNaN : boolean = true – indicates that this object has an NaN numeric value (i.e., Number.isNan(this.number) === true)Methods:
Examples:
let yt_nan = factory.double(NaN);
yt_nan.value; // NaN
yt_nan.isolate(); // '{termType:'Literal', value:'NaN', language:'', datatype:{termType:'NamedNode', value:'http://www.w3.org/2001/XMLSchema#double', }, }'
yt_nan.verbose(); // '"NaN"^^<http://www.w3.org/2001/XMLSchema#double>'
yt_nan.terse(); // '"NaN"^^<http://www.w3.org/2001/XMLSchema#double>'
yt_nan.isNumeric; // true
yt_nan.isDouble; // true
yt_nan.isNaN; // true
yt_nan.number; // NaN
A class that represents an RDF quad.
Properties:
.subject : NamedNode | BlankNode.predicate : NamedNode.object : NamedNode | BlankNode | Literal.graph : NamedNode | BlankNode | DefaultGraphMethods:
equals(other: AnyQuad)
booleanverbose()
terse([prefixes: #hash/prefix-mappings])
concise([prefixes: #hash/prefix-mappings])
.subject: #string/quad-term.predicate: #string/quad-term.object: #string/quad-term.graph: #string/quad-termisolate()
Examples:
graphy.content.ttl.read('<http://ex.org/unit-circle> <http://ex.org/area> 3.141592653589793 .', {
data(y_quad) {
y_quad.isolate(); // {subject:{termType:'NamedNode', value:'http://ex.org/unit-circle', }, predicate:{termType:'NamedNode', value:'http://ex.org/area', }, object:{termType:'Literal', value:'3.141592653589793', language:'', datatype:{termType:'NamedNode', value:'http://www.w3.org/2001/XMLSchema#decimal', }, }, graph:{termType:'DefaultGraph', value:'', }, }
y_quad.verbose(); // <http://ex.org/unit-circle> <http://ex.org/area> "3.141592653589793"^^<http://www.w3.org/2001/XMLSchema#decimal> .
y_quad.terse(); // <http://ex.org/unit-circle> <http://ex.org/area> 3.141592653589793 .
y_quad.terse({ex:'http://ex.org/'}); // ex:unit-circle ex:area 3.141592653589793 .
},
});
Any object with the given properties defined, including plain objects. By definition, any instance of an @RDFJS/Term or GenericTerm also meet these criteria.
.termType : 'NamedNode' | 'BlankNode' | 'Literal' | 'DefaultGraph'.value : string.datatype : AnyTerm.language : #string/language-tagAny object with the given properties defined, including plain objects. By definition, any instance of an @RDFJS/Quad or Quad also meet these criteria.