Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@tpluscode/rdfine

tpluscode2.5kMIT0.7.11TypeScript support: included

RDF/JS idiomatic, native, effective

rdf, rdfjs, entity, decorator, clownface, graph

readme

RDFine /rɪdɪˈfaɪn/

RDF/JS i*diomatic, *native, enjoyable

NPM version Build codecov.io

About

Idiomatic

RDFine greatly simplifies the manipulation of data in RDF graph (RDF/JS datasets) by wrapping low-level node handling of triples in plain JavaScript objects.

It is also possible to share the JS-RDF bindings between projects as npm packages.

Native

While plain JS objects are the preferred way to access the graphs, they do not completely replace the underlying RDF/JS dataset. Both RDFine objects and the dataset can be modified simultaneously, with changes to one immediately reflected in the other.

Effective

RDFine makes it super easy to bootstrap a triple-backed project without the need to drink up the RDF Kool-Aid. Novices will use the idiomatic JS interface to get the job done quickly, while power users still can take advantage of seamless integration with @rdfjs libraries.

TL;DR; overview

You have RDF triples in an RDF/JS Dataset object

@prefix ex: <http://rdfine.ggg/> .
@prefix schema: <http://schema.org/> .

ex:john a schema:Person ; 
    schema:name "John Doe" ;
    schema:spouse ex:jane ;
    schema:nationality [
        schema:name "USA"
    ] .

You want to create a JS object model to access that data

import {schema} from '@tpluscode/rdf-ns-builders'
import { namedNode } from '@rdfjs/data-model'
import { RdfResourceImpl, fromObject } from '@tpluscode/rdfine'
import { loadData } from './data/person'
import { Person, PersonMixin } from './model/Person'

// make rdfine "aware" of object model for schema:Person
RdfResourceImpl.factory.addMixin(PersonMixin)

// create entity through the factory
const john = RdfResourceImpl.factory.createEntity<Person>({
  dataset: await loadData(),
  term: namedNode('http://rdfine.ggg/john'),
})

// modify the dataset through JS objects
john.nationality = "United States of America"
// also with deep graph modifications
john.spouse = fromObject({
  types: [schema.Person],
  name: 'Jane Doe',
})

// get the modified dataset, always in sync
const dataset = john._selfGraph.dataset

Installation

`shell script npm i @tpluscode/rdfine


## 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.

```typescript
// Person.ts
import { Constructor, namespace, property, RdfResource } from '@tplusode/rdfine'
import { Term } from '@rdfjs/types'
import { namedNode } from 'rdf-data-model'

// TS: define an interface for your object 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 {

    // Literal property
    // By default use the property's name with the annotated @namespace    
    @property.literal()
    name!: string  // http://schema.org/name

    // Customize the getter to return objects of a certain property
    @property.resource({
      // http://schema.org/knows
      path: 'knows',
      // always return a JS array
      values: 'array'
    })
    friends!: Person[]

    // getting raw RDF/JS terms
    // by annotating with plain @property
    @property({ 
      path: 'http://www.w3.org/2000/01/rdf-schema#label'
    })
    label: Term

    // use _selfGraph property to access raw triples
    // by traversing the graph with https://github.com/zazuko/clownface
    get hasOccupation(): boolean {
      return this._selfGraph
        .out(namedNode('http://schema.org/hasOccupation'))
        .terms.length > 0
    }
  }

  return P
}

// add a function to decide if the underlying resource
// satisfies the Person interface
// for example by checking its RDF types
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 '@rdfjs/types'
import { namedNode } from 'rdf-data-model'
import { RdfResourceImpl } from '@tpluscode/rdfine'
import { Person, PersonMixin } from './Person'

// register the mixin type with the factory
factory.addMixin(PersonMixin)

// load you RDF triples into a RDF/JS dataset
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._selfGraph.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

  1. npm i -D @babel/preset-env @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties
  2. Configure babel (for example with .babelrc)
     {
       "presets": [
         "@babel/env"
       ],
       "plugins": [
         [
           "@babel/plugin-proposal-decorators",
           {
             "decoratorsBeforeExport": true
           }
         ],
         [
           "@babel/plugin-proposal-class-properties"
         ]
       ]
     }

changelog

Change Log

0.7.11

Patch Changes

  • c41dbdd7: Updated @zazuko/env

0.7.10

Patch Changes

  • 0d2863f0: Replace once with onetime

0.7.9

Patch Changes

  • 86de16ae: Fix imports to work with moduleResolution: NodeNext

0.7.8

Patch Changes

  • 0dfe5271: Use the slimmer @zazuko/env which works better in the browser

0.7.7

Patch Changes

  • 9b28f347: Updated dependencies to remove rdf-js references in compiled output

0.7.6

Patch Changes

  • 3dac56f6: Remove imports of clownface. Remove dependency on @tpluscode/rdf-ns-builders.

0.7.5

Patch Changes

  • 965859d7: Update to @rdfjs/environment v1 and @zazuko/env v2

0.7.4

Patch Changes

  • b110aab2: toJSON would not correctly serialise lists when the value did not match annotated property

0.7.3

Patch Changes

  • 3c90fafa: Use mapped type to declare vocabulary factory

0.7.2

Patch Changes

  • 959e53cf: There were factories missing in the environment

0.7.1

Patch Changes

  • 3d337f9b: Missing dataset factory in RdfineEnvironment type

0.7.0

Minor Changes

  • fe473333: Decorator @namespace does not allow string any more

0.6.0

Minor Changes

  • 6cee88c8: Package is not ESM-only

0.5.43

Patch Changes

  • 29474b07: It would still be impossible to initialise literal prop, when it allowed undefined

0.5.42

Patch Changes

  • e07c0889: Initializing literal properties triggered design-time type error when initialised from a plain JS (string, number ,etc)

0.5.41

Patch Changes

  • 1cd0c024: Initializer module missing in CJS build

0.5.40

Patch Changes

  • 09714d17: RDF List initializer made simpler a helper function. For example, to initialize a ( 'foo', 'bar', 'baz ) list:

    import * as initialize from "@tpluscode/rdfine/initializer";
    
    let node;
    const resource = fromPointer(node, {
      listProp: initialize.rdfList("foo", "bar", "baz")
    });

    closes (#143)

0.5.39

Patch Changes

  • f7cfefff: Update @tpluscode/rdf-ns-builders to v2

0.5.38

Patch Changes

  • 5cb8a316: Make @types/clownface a regular dependency (re hypermedia-app/Alcaeus#288)

0.5.37

Patch Changes

  • 32a92788: fromPointer function did not work due to inaccurate types

0.5.36

Patch Changes

  • a2484ec2: Initializer factory only allowed URI nodes

0.5.35

Patch Changes

  • 76c13f14: Fix peer dependencies (re hypermedia-app/shaperone#173)

0.5.34

Patch Changes

  • 292c9d7b: Possibility for setting properties using factories (fixes #191)
  • 292c9d7b: Pointers could not have been set to proxied properties

0.5.33

Patch Changes

  • 658c9e98: Optimise setting URI property from existing resource object
  • 7a52025d: Initializing URI property with factory would throw

0.5.32

Patch Changes

  • 20f5f01c: Initializing properties with factory functions

0.5.31

Patch Changes

  • 64e8907e: Filter decorator option

0.5.30

Patch Changes

  • 6207e784: Fix serialization of list of literals to JSON

0.5.29

Patch Changes

  • 247137f2: Extending interface relaxed to allow Partial base class

0.5.28

Patch Changes

  • 377c603b: Update typing which appears to cause an error TS2344: Type 'T' does not satisfy the constraint 'RdfResourceCore<DatasetCore<Quad, Quad>>' on later versions of TypeScript

0.5.27

Patch Changes

  • a63ec35a: Update @tpluscode/rdf-ns-builders and typescript RDF/JS types

0.5.26

Patch Changes

  • 97c0dd19: toJSON: serialize lists which are not strongly typed properties
  • 0a04fa75: Initializing optional properties only allowed arrays

0.5.25

Patch Changes

  • abcdf51a: Setting Term property from resource initializer
  • 7b624685: It was impossible to set a Date directly to an annotated Term property
  • b03ad19f: Build: break import cycle between modules

0.5.24

Patch Changes

  • 6ca3a8a6: toJSON: exception thrown when serializing literals

0.5.23

Patch Changes

  • b2af1429: Property which allows lists and single element should not initalize RDF List with single item

0.5.22

Patch Changes

  • a721bc7d: Fix initilizer build issue caused in 0.5.20

0.5.21

Patch Changes

  • b60897cf: Initializer incorrectly mapped RdfResourceCore properties

0.5.20

Patch Changes

  • 5f084146: Types initialied with TypeCollection are not added
  • 1448f1bb: Initializing nested resources using typed interface

0.5.19

Patch Changes

  • fa277552: Date initializer should set value

0.5.18

Patch Changes

  • d5a614bd: Missing export of @tpluscode/rdfine/factory

0.5.17

Patch Changes

  • 60a925e4: Generating mixins extending other vocabs
  • e2d18bb7: Add factory method to mixin modules

0.5.16

Patch Changes

  • a4e39c35: It is now possible to use typed namespace builder with decorator
  • 07d94285: Relax the Term type requirement of equals
  • 69eb2666: Not all properties from all mixins were initialized

0.5.15

Patch Changes

  • b88ea8f: Node terms were incorrectly serialized as string by toJSON

0.5.14

Patch Changes

  • 97309a8: toJSON: handle literals without datatype

0.5.13

Patch Changes

  • a45b17b: Use annotated types to initialize resource nodes

0.5.12

Patch Changes

  • 904b109: Handle initilizer with plain string id

0.5.11

Patch Changes

  • 6000ce8: @property decorator was unusable with augmented RdfResource interface

0.5.10

Patch Changes

  • 1aec204: toJSON did not walk the prototype chain

0.5.9

Patch Changes

  • 677f160: Use @namespace when serializing properties in toJSON

0.5.8

Patch Changes

  • 1ea983b: Extract base resource interface to allow augmentation

0.5.7

Patch Changes

  • d69277a: Generated resource types should all have generic dataset argument
  • 9986b77: Resource proxy now handles Symbols
  • fecafe1: Added a toJSON resource method which creates a JSON-LD object of object's graph

0.5.6

Patch Changes

  • c5b2570: It was not possible to initialize T | T[] property

0.5.5

Patch Changes

  • 7438e0b: Update to @types/rdf-js v4

0.5.4

Patch Changes

  • 6c016d1: Added support for xsd date/dateTime/time

0.5.3

Patch Changes

  • da8114f: Construct correct base class when overriding in factory call

0.5.2

Patch Changes

  • 1abc238: Add export declaration for TypeCollection

0.5.1

Patch Changes

  • a9e85e3: Add export of ResourceFactory

0.5.0

Minor Changes

  • 98d991a: Update clownface, renamed pointer property

0.4.24

Patch Changes

  • c1e1e19: Allow properties to return both arrays/lists as well as single values

0.4.23

Patch Changes

  • 5316ea6: Add support for custom datatypes

0.4.22 (2020-08-07)

Bug Fixes

  • mixin cannot be defined to use specific dataset (1420094)

0.4.21 (2020-08-06)

Bug Fixes

0.4.20 (2020-07-07)

Bug Fixes

  • unable to initialize arrays with http properties (2791c90)

0.4.19 (2020-07-07)

Features

  • comparing resources also with nodes and pointers (bfaf2dd)
  • initializing resource with any property (0c5f763)

0.4.18 (2020-07-06)

Bug Fixes

  • build: exports field did not work in newer node (531da7b)

0.4.17 (2020-07-05)

Bug Fixes

  • make all type exports explicit (0030d8f)

0.4.16 (2020-07-03)

Bug Fixes

  • resource: fix bnode id equality (c13c821)

0.4.15 (2020-06-08)

Note: Version bump only for package @tpluscode/rdfine

0.4.14 (2020-05-06)

Bug Fixes

  • core: slight perf boost by skipping unnecessary mixins (101f7a3)
  • core: type cache incorrectly created (21e16e6)

0.4.13 (2020-05-05)

Features

  • core: improve performance by memoizing runtime classes (1cdc7ee)

0.4.12 (2020-04-29)

Features

  • add option to resource decorator to add assert implied types (90f1b7a)

0.4.11 (2020-04-28)

Note: Version bump only for package @tpluscode/rdfine

0.4.10 (2020-04-28)

Note: Version bump only for package @tpluscode/rdfine

0.4.9 (2020-04-25)

Bug Fixes

  • method getArray should only read resources (451201e)

0.4.8 (2020-04-22)

Features

  • add more helpful getters to base class (2e67a81)

0.4.7 (2020-04-21)

Features

  • add a handy getter to check blank node resource (#54) (d3d5731)

0.4.6 (2020-04-21)

Features

  • keep track of parent resource (ef48ec5)

0.4.5 (2020-04-19)

Bug Fixes

  • core: initializing term properties with raw nodes (eb6aa49)

0.4.4 (2020-04-19)

Features

  • initializing with clownface objects (c3ac5a5)

0.4.3 (2020-04-18)

Bug Fixes

  • core: make it possible initialize with RDF/JS terms (56e13bd)

0.4.2 (2020-04-15)

Bug Fixes

  • getter throws when selecting all node by dataset is empty (4e5e4f5)

0.4.1 (2020-04-15)

Bug Fixes

  • subject from all graph did not work (9d3497b)

0.4.0 (2020-04-01)

Features

  • build: only package es modules and esm node export (4d5fa5b)

BREAKING CHANGES

  • build: some exports have been moved

0.3.7 (2020-03-25)

Bug Fixes

  • core: clownface used to create resource would fail (02a4be9)
  • core: simplify resource initialization (cfc6731)

0.3.6 (2020-03-25)

Bug Fixes

  • core: plain intialization impossible with union type properties (a545e48)
  • simplify the creation of resources (1077cb1)

Features

  • generator: create classes which can be easily initialized (3fb0900)
  • first draft of schema.org package (feaa2df)
  • handle deep initialization from plain object (0fd30af)

Changelog

All notable changes to this project will be documented in this file. See standard-version for commit guidelines.

0.3.5 (2020-02-04)

Bug Fixes

  • type collection is not exported (3bafaf2)

0.3.4 (2020-02-04)

0.3.3 (2020-02-04)

Features

  • (optional) type collection to work over all graphs (752ce18)

0.3.2 (2020-01-31)

Bug Fixes

  • package missing the declaration files (310a632)

0.3.1 (2020-01-31)

Bug Fixes

  • export ResourceFactory from main (d278638)

0.3.0 (2020-01-31)

⚠ BREAKING CHANGES

  • replaces _node property with _selfGraph

Features

  • named graph must be explicitly traversed in isolation (902a7a6)

Bug Fixes

  • decorator: make generic annotation more accurate (4707b0b)
  • factory: depend on interface and not implementation (0a67270)

0.2.12 (2020-01-30)

Features

  • ability to add multiple mixins at once (9cb5595)
  • allow setting initial value as clownface node (82ca518)

0.2.11 (2020-01-27)

Bug Fixes

  • types property should be declared as interface (141624c)

0.2.10 (2020-01-27)

Bug Fixes

  • initial property value does not work with array properties (c400565)

0.2.9 (2020-01-26)

Bug Fixes

  • revisit the type declaration for ResourceIndexer (34d57ca)

0.2.8 (2020-01-23)

Bug Fixes

  • proxy indexer also returns rdf lists as array (9cd04bd)

0.2.7 (2020-01-22)

Bug Fixes

  • add resource indexer to RdfResource._create (f1deedb)

0.2.6 (2020-01-21)

Features

0.2.5 (2020-01-20)

Features

  • export indexer interface (aea91a8)

0.2.4 (2020-01-20)

Bug Fixes

  • add generic type argument to mark base class (e65e111)

0.2.3 (2020-01-17)

Features

  • export a resource identitifier term type (d13a4cd)

0.2.2 (2020-01-17)

0.2.1 (2020-01-16)

Bug Fixes

  • relax the typings of create method (5c98a21)

0.2.0 (2020-01-15)

⚠ BREAKING CHANGES

  • decorator's array: boolean changed to values: 'array' | 'list' | undefined

Features

  • allow setting RDF arrays (7d83311)

Bug Fixes

  • more informative getter/setter exceptions (621c6c9)

0.1.4 (2020-01-13)

Features

  • equals method to compare resource instances (#19) (421c5a4)
  • instance method to create resources (bab524d)

Bug Fixes

  • proxy returns array for single object (dd40473)

0.1.3 (2020-01-11)

Features

  • wrap object in proxy to allow arbitrary property access (3a08b8c)

0.1.2 (2020-01-09)

Features

  • read-only support for rdf lists (1849150)

Bug Fixes

  • decorators fail to apply with babel (dcd0ca0)
  • strict property throws when initialized declaratively (a7088ff)

0.1.1 (2020-01-08)

Features

  • added TypeCollection class and resource prop (60a10d6)

0.1.0 (2019-12-30)

⚠ BREAKING CHANGES

  • a factory instance must exist on the base class

Features

  • allow decorated base class override (6628435)
  • basic support for numeric literals (34c6f2f)
  • dafault property value (c1e9c57)
  • declare initial prop value as factory function (4849b98)
  • strict properties (d4fe5c1)

  • remove singleton factory (723c504)

0.0.2 (2019-12-23)

0.0.1 (2019-12-22)

Features

  • annotating properties to use namespaces (baf7493)
  • implement resource factory as singleton (bc14c7d)
  • postel law - set terms directly (cc88849)
  • setting and unsetting resource relations (05ff089)
  • setting string and boolean literals (71ed349)
  • setting string and boolean literals (386a940)

Bug Fixes