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 === Object
The 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
= true
Methods:
equals(other:
AnyTerm
)
boolean
verbose()
#string/term_verbose
terse(prefix_map:
#hash/prefix-mappings
)
#string/term_terse
concise(prefix_map:
#hash/prefix-mappings
)
#string/term_concise
isolate()
– 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 whatfalse
Examples:
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
|
DefaultGraph
Methods:
equals(other:
AnyQuad
)
boolean
verbose()
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.