1.1.0 • Public • Published

graphy NPM version Build Status Dependency Status

Abstracts JSON-LD objects with an API for easy traversal and exploration of an RDF graph programatically. It emphasizes the use of iterators and namespaces to access entities by their suffix.



$ npm install --save graphy


Take the following graph:

@prefix ns: <vocab://ns/> .
@prefix color: <vocab://color/> .
@prefix plant: <vocab://plant/> .
@prefix xsd: <> .
@prefix rdf: <> .
@prefix rdfs: <> .

	ns:contains plant:Seeds .

	a ns:Food, plant:Fruit, plant:EdiblePart;
	rdfs:label "Banana"^^xsd:string;
	ns:tastes "good" ;
	ns:shape "curved"^^ns:Liberty ;
	ns:data 25 ;
	ns:appears color:Yellow ;
	ns:class ns:Berry ;
	plant:blossoms ns:YearRound ;
	ns:alias ns:Cavendish, ns:Naner, ns:Bananarama ;
	ns:stages (
	) ;
	ns:considered [
		a plant:Clone, plant:Fruit
	] .

Here, example.json is a JSON-LD file generated from the graph above:

var graphy = require('graphy');
var json_ld = require('./example.json');

graphy(json_ld, (q_network) => {
	// select a node from the graph by IRI; set accessor namespace to `ns:` prefix
	let k_banana ='ns:Banana').$('ns:');

	// get IRI of node
	k_banana['@id']; // 'vocab://ns/Banana'
	k_banana.$id(); // 'Banana'

	// get `rdf:type` property(s) of node
	k_banana['@type']; // ['vocab://plant/Fruit', 'vocab://ns/Food']
	k_banana.$types(); // ['Food']
	k_banana.$type(); // 'Food'
	k_banana.$types('plant:'); // ['Fruit']
	k_banana.$type('plant:'); // 'Fruit'

	// get value of a literal
	k_banana.tastes(); // 'good'
	k_banana.shape(); // 'curved'

	// get absolute datatype of a literal
	k_banana.shape['@type']; // 'vocab://ns/Liberty'
	k_banana.tastes['@type']; // ''

	// get suffixed datatype of a literal
	k_banana.shape.$type(); // 'Liberty'

	// set terminal namespace to get suffixed datatype of literal
	k_banana.tastes.$type(); // undefined
	k_banana.tastes.$type('xsd:'); // 'string'

	// properties of an IRI in same accessor namespace
	k_banana.class(); // 'Berry'
	k_banana.class.$id(); // 'Berry'
	k_banana.class['@id']; // 'vocab://ns/Berry'
	k_banana.class['@type']; // '@id'

	// properties of an IRI in different namespace
	k_banana.appears(); // undefined
	k_banana.appears('color:'); // 'Yellow'
	k_banana.appears.$id(); // undefined
	k_banana.appears.$id('color:'); // 'Yellow'
	k_banana.appears['@id']; // 'vocab://color/Yellow'
	k_banana.appears['@type']; // '@id'

	// changing accessor namespace
	k_banana.$types('plant:'); // ['Fruit', 'EdiblePart']
	k_banana.$('plant:').blossoms(); // undefined
	k_banana.$('plant:').blossoms['@id']; // 'vocab://ns/YearRound'
	k_banana.$('plant:').blossoms('ns:'); // 'YearRound'

	// get SPARQL/TTL-compatible string representation of any entity
	k_banana.$n3(); // 'ns:Banana'
	k_banana.$n3(false); // '<vocab://ns/Banana>'
	k_banana.appears.$n3(); // 'color:Yellow'
	k_banana.tastes.$n3(); // '"good"^^xsd:string'
	k_banana.tastes.$n3.value(); // '"good"'
	k_banana.tastes.$n3.datatype(); // 'xsd:string'

	// ...cont'd
	k_banana.class.$n3(); // 'ns:Berry'
	k_banana.class.$nquad(); // '<vocab://ns/Berry>'
	k_banana.tastes.$nquad(); // '"good"^^<>'
	k_banana.stages.$n3(); // '[rdf:first ns:FindSpace; rdf:rest (plant:Seed plant:Grow plant:Harvest)]'
	k_banana.stages.$n3(false); // '[<> <vocab://ns/FindSpace>;<> (<vocab://plant/Seed> <vocab://plant/Grow> <vocab://plant/Harvest>)]'

	// type indicators
	k_banana.$is(); // 'node'
	k_banana.$is.node; // true

	// ...cont'd
	k_banana.appears.$is(); // 'iri'$is(); // 'literal'
	k_banana.stages.$is(); // 'collection'
	k_banana.considered.$is(); // 'blanknode'

	// ...cont'd
	k_banana.$is.node; // true
	k_banana.appears.$is.iri; // true$is.literal; // true
	k_banana.stages.$is.iri; // undefined
	k_banana.stages.$is.literal; // undefined
	k_banana.stages.$is.collection; // true
	k_banana.considered.$is.blanknode; // true

	// predicates with multiple objects
	k_banana.alias; // emits warning: 'more than one triple share the same predicate "ns:alias" with subject "ns:Banana"; By using '.alias', you are accessing any one of these triples arbitrarily'

	// ..contd'
	let a_items = k_banana('alias', function(k_alias) { // implicit `.map` callback
		return k_alias();
	a_items; // ['Cavendish', 'Naner', 'Bananarama']

	// collections
	k_banana.stages().map(function(k_stage) {
		return k_stage.$id() || k_stage.$id('plant:');
	}); // ['FindSpace', 'Seed', 'Grow', 'Harvest']

	// collections: (equivalent to above) implicit `.map`
	k_banana.stages(function(k_stage) { // implicit `.map` callback
		return k_stage.$id() || k_stage.$id('plant:');
	}); // ['FindSpace', 'Seed', 'Grow', 'Harvest']

	// collections: implicit array accessor
	k_banana.stages(0).$id(); // 'FindSpace'
## Iterating


An entity of type node supports iteration directly on the reference itself. The key of the iterator will be the predicate suffixed by the current accessor namespace, the value of the iterator will be an array of entities that are pointed to by that predicate:

for(let [s_predicate_suffix, a_objects] of k_banana) {
	a_objects.forEach((k_node) => {
		console.log(s_predicate+' => {'+k_node.$is()+'} '+k_node.$n3());

// alias => {iri} ns:Cavendish
// alias => {iri} ns:Naner
// alias => {iri} ns:Bananarama
// appears => {iri} color:Yellow
// class => {iri} ns:Berry
// considered => {blanknode} _:b4
// data => {literal} "25"^^xsd:integer
// stages => {collection} [rdf:first ns:FindSpace;rdf:rest (plant:Seed plant:Grow plant:Harvest)]
// ...

You can also iterate on the no-args call of a node entity, this will set the namespace to an empty string so that the key of each iterator is the full IRI of each predicate:

for(let [p_predicate, a_objects] of k_banana()) {  // same as k_banana.$('')
	a_objects.forEach((k_node) => {
		console.log(q_graph.shorten(p_predicate)+' => {'+k_node.$is()+'} '+k_node.$n3());

// ns:alias => {iri} ns:Cavendish
// ns:alias => {iri} ns:Naner
// ns:alias => {iri} ns:Bananarama
// ns:appears => {iri} color:Yellow
// plant:blossoms => {iri} ns:YearRound
// ns:class => {iri} ns:Berry
// ...

RDF Collections

Collection objects are arrays that are also an entity.

In order to be consistent with the graph, rdf collection properties are emulated on collection objects. So instead of accessing a collection's elements via Array's properties/methods, you can also use the rdf:first and rdf:rest properties:

let w_list = k_banana.stages.$('rdf:');

w_list.first.$id('ns:'); // 'FindSpace'

w_list =;
w_list.first.$id('plant:'); // 'Seed'

w_list =;
w_list.first.$id('plant:'); // 'Grow'

w_list =;
w_list.first.$id('plant:'); // 'Harvest'

w_list =;
w_list.$id('rdf:'); // 'nil'

// ------------ or in a loop ------------
let a_stages = [];
let w_list = k_banana.stages.$('rdf:');
while(w_list.$id('rdf:') !== 'nil') {
	a_stage.push(w_list.first.$id('plant:') || w_list.first.$id('ns:'));
	w_list =;
a_stages; // ['FindSpace', 'Seed', 'Grow', 'Harvest']
# API Reference
## Graphy The module itself.

graphy(jsonld: Jsonld_object, ready: function)

Calls ready(network: Network) once a graphy network has been created for the given jsonld object.

## Network An array of the jsonld objects in this graph, each represented by a graphy [entity](#entity). ### string[, namespace: string]) Returns the graphy entity for the IRI given by `name`, which may be a prefixed name or full IRI. Optional `namespace` argument will set the accessor namespace for the returned object (see [entity.$()](#e.$)). ###[map: function]) Returns an array of only entities that are named things (ie not blanknodes) or blanknodes that do not appear in the object position of any triples in the current graph. These can be thought of as top-level nodes. Accepts an optional `map` function callback to transform the entities before returning the array. These entities will have empty an accessor namespace by default. ### network.shorten(iri: string) Shortens an IRI using prefixes defined in the @context of the original jsonld object. ### network.[...] [Network](#network) is an array, so it supports all native functions. Each item in the array is a graphy entity with an empty accessor namespace.
## Entity A reference to an RDF entity/jsonld object covered by the set of methods/properties documented in this section. An entity can be obtained by [``](, or any one of the array interface methods on network. ### entity() > Only for types: `node`

Returns a Map of {predicate => object} pairs for all triples stemming from this entity as the subject. The key of each pair is a string representing the full predicate IRI, the value is an entity representing the object.

entity([namespace: string])

Only for types: iri

Returns the IRI of this entity suffixed by the current accessor namespace or the namespace argument if it is used. You can obtain the full IRI no matter the current accessor namespace by using an empty string for namespace.


Only for types: literal

Returns the value portion of the literal. See entity.$type and entity.$n3.datatype for getting the datatype of a literal.

entity(access_name: string)

Only for types: node

Returns an array of entities that are pointed to by the namespaced predicate suffix access_name. If the current accessor namespace is empty, then the access name would be the full IRI of the predicate.

### entity(access_name: string[, map_callback: function]) > Only for types: `node`

Same as entity() except that it maps every object pointed to by access_name to the given map_callback function before returning the array of entities.


Only for types: collection

Returns the array

entity(item_index: integer)

Only for types: collection

Returns the item at item_index in the collection.

entity(map_callback: function)

Only for types: collection

Applies the given map_callback to every item in the array and returns the resulting array.

### entity.$(namespace: string) Sets the accessor namespace of the returned object to the expanded version of the IRI given by `namespace`, may be either an n3 prefix or a full IRI. By chaining this call, you can change the accessor namespace on the same line to access properties or IRIs by their suffix.


This no-args version of the namespace method will instead return the full IRI of the current accessor namespace.

### entity.$namespaces() Returns a hash whose values are entities of this node under different namespace accessors; one for each IRI prefix in the JSON-LD document's context (which is the key of each key-value pair).
// destructuring assignment
let {rdfs, owl, other} = banana.$namespaces();
rdfs.label; // 'Banana'
other.ns.tastes(); // 'good'


This no-args version of the namespace method will instead return the full IRI of the current accessor namespace.

### entity.$n3() Returns a terse n3 representation of the current entity as a string. It is prefixed by the longest matching URI available in the original JSON-LD context, unless the resulting suffix would contain invalid characters for a prefixed IRI in either SPARQL or TTL. The string is compatible with SPARQL and TTL as long as the corresponding prefix is also included in the document. ### entity.$n3.datatype() > Only for types: `literal`

Returns the IRI datatype of this literal in terese n3 form.

### entity.$nquad() Returns the n-quad representation of this entity. Useful for serializing to SPARQL/TTL without worrying about prefixes. > Caution: `.$nquad()` does not currently support nested RDF collections (it will produce blanknode collisions) ### entity.$in(namespace: string) Returns true if the current entity's IRI is in the given `namespace`. Will always return false for blanknodes, collections and literals. ### entity.$is() Calling this function returns the reference type of this entity as a string. You can also use a shorthand check by testing if `.$is[ref_type]` is defined as `true`. eg: `if(entity.$is.iri === true) ...`. Possible values for type are: - *node* - this entity exists as the subject of some triple(s). This entity contains predicates that point to objects - *iri* - this is a mere symbollic reference to an IRI, which exists as the object of some triple. If you encounter this type, it means that you reached a named thing (ie: not a blanknode). Use [`entity.$node()`](#e.node) to obtain the node of this IRI if it exists in the current graph - *literal* - an RDF literal - *collection* - an RDF collection ### entity.$node([namespace: string]) > Only for types: `iri`

Will return the node object for accessing triples that have this IRI as its subject. If there are no triples in the current jsonld graph that have this IRI as its subject, calling .$node() will return undefined for this IRI. Passing an optional namespace argument will set the accessor namespace on the returned graphy entity.

### entity['@id'] Reflects the json-ld `@id` property. ### entity.$id([namespace: string]) The suffix of the `@id` property after removing the current accessor namespace from the beginning. If the current accessor namespace does not match, or this IRI is a blanknode, this method will return `undefined`. If a `namespace` argument is passed, the method will use the given `namespace` instead of the current accessor namespace to suffix the IRI. ### entity['@type'] Reflects the json-ld `@type` property. For literals, this will be the datatype. For nodes, this will be an array of objects pointed to by the `rdf:type` predicate. ### entity.$types > Only for types: `node`

An array of graphy IRI entities that are pointed to by the @type property (which is the rdf:type predicate) for this entity.

### entity.$types([namespace: string]) > Only for types: `node`

Returns an array of strings that are the suffixes of the IRIs pointed to by the @type property after removing the current accessor namespace (or the given namespace argument) from the beginning of the IRI. If the namespace does not match any of the IRIs, this will return an empty array [].

### entity.$type([namespace: string]) > Only for types: `node`

Shortcut for .$types(..)[0]. If this node entity has more than one rdf:type, accessing this property will issue a warning. If the current accessor namespace does not match any of the IRIs, this will return undefined. If a namespace argument is passed, the method will use the given namespace instead of the current accessor namespace to suffix the IRI.

entity.$type([namespace: string])

Only for types: literal

Returns the datatype of this literal entity suffixed by the current accessor namespace or the namespace argument if it is used.


ISC © Blake Regalia


npm i graphy@1.1.0





Last publish


  • blake.regalia