RDFine /rɪdɪˈfaɪn/
RDF/JS idiomatic, native, enjoyable
Installation
npm i @tplusode/rdfine
Also peer @types
dependencies:
npm i --save-dev @types/clownface @types/rdf-ext @types/rdfjs__namespace
Usage
Define resource interfaces
While it is possible to inherit a base resource class, it's best to create partial mixin classes
which implement part of the RDF model. Mixins are dynamically applied to compose a JavaScript object model
closely matching the actual quad data.
import { Constructor, namespace, property, RdfResource } from '@tplusode/rdfine'
import { Term } from 'rdf-js'
import { namedNode } from 'rdf-data-model'
export interface Person extends RdfResource {
name: string
friends: Person[]
}
export function PersonMixin<Base extends Constructor>(base: Base) {
@namespace('http://schema.org/')
class P extends base implements Person {
@property.literal()
name!: string
@property.resource({
path: 'knows',
values: 'array'
})
friends!: Person[]
@property({
path: 'http://www.w3.org/2000/01/rdf-schema#label'
})
label: Term
get hasOccupation(): boolean {
return this._node
.out(namedNode('http://schema.org/hasOccupation'))
.terms.length > 0
}
}
return P
}
PersonMixin.shouldApply = (res: RdfResource) => {
return res.hasType('http://schema.org/Person')
}
Creating resource instances
Instead of directly creating resource types, which would require deciding up-front, which
mixins to add to the constructed class, a factory can be used.
import { DatasetCore } from 'rdf-js'
import { namedNode } from 'rdf-data-model'
import { RdfResourceImpl } from '@tpluscode/rdfine'
import { Person, PersonMixin } from './Person'
factory.addMixin(PersonMixin)
let dataset: DatasetCore = loadRdfData()
const person = RdfResourceImpl.factory.createEntity<Person>({
dataset,
term: namedNode('http://example.com/gh/tpluscode')
})
Use it!
The setters are immediately reflected in the underlying dataset.
Note that any property can also be set with raw RDF term matching the annotated type
import { namedNode } from 'rdf-data-model'
person.name = "Tomasz"
person.friends = [
namedNode('http://example.com/gh/bergos'),
namedNode('http://example.com/gh/ktk')
] as any
console.log(person._node.dataset.toString())
The last line above will print triples equivalent to those below
@prefix schema: <http://schema.org/> .
<http://example.com/gh/tpluscode>
schema:name "Tomasz" ;
schema:knows <http://example.com/gh/bergos> , <http://example.com/gh/ktk> .
Using with babel
npm i -D @babel/preset-env @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties
- Configure babel (for example with
.babelrc
)
{
"presets": [
[
"@babel/env"
],
"plugins": [
[
"@babel/plugin-proposal-decorators",
{
"decoratorsBeforeExport": true
}
],
[
"@babel/plugin-proposal-class-properties"
]
]
}