@rdfjs/wrapper
    Preparing search index...

    @rdfjs/wrapper

    RDF/JS Wrapper

    Test Workflow npm

    An RDF/JS object mapping library.

    The purpose of the RDF/JS Wrapper library is to enable idiomatic JavaScript object-oriented programming over RDF with type system support (TypeScript compatible).

    In other words, RDF data is abstracted away and developers can define standard mapping classes to program over it.

    Additionally, standard mapping classes can be defined and reused in any number of context where they are relevant (see for example @solid/object).

    A guide and demo for using this library in the context of Solid and Next.js is available here.

    A script for generating mapping classes from SHACL shapes is available here.

    In order to wrap RDF, one needs an underlying data structure. Therefore, both TermWrapper and DatasetWrapper take an RDF/JS Dataset and Datafactory as constructor parameters.

    Term wrapping lets you manipulate data in a graph via class properties.

    A term wrapper instantiates a class from a term.

    For example you can write a Person class with one name property:

    import { TermWrapper, LiteralAs, LiteralFrom } from "https://unpkg.com/@rdfjs/wrapper"

    class Person extends TermWrapper {
    get name() {
    return this.singularNullable("https://example.org/name", LiteralAs.string)
    }

    set name(value) {
    this.overwriteNullable("https://example.org/name", value, LiteralFrom.string)
    }
    }

    Assuming the following RDF has been loaded in a dataset dataset_x:

    PREFIX ex: <https://example.org/>

    ex:person1 ex:name "Alice" .

    Class usage:

    const person1 = new Person("https://example.org/person1", dataset_x, DataFactory)

    // Get property
    console.log(person1.name)
    // outputs "Alice"

    // Set property
    person1.name = [...person1].reverse().join("")
    console.log(person1.name)
    // outputs "ecilA"

    Dataset wrapping lets you find data in a graph that is meant to be wrapped.

    For example, you can write a People dataset wrapper to find each Person in a graph:

    class People extends DatasetWrapper {
    [Symbol.iterator]() {
    return this.subjectsOf("https://example.org/name", Person)
    }
    }

    Assuming the following RDF has been loaded in a dataset dataset_y:

    PREFIX ex: <https://example.org/>

    ex:person1 ex:name "Alice" .
    ex:person2 ex:name "Bob" .

    Dataset Wrapper usage:

    const people = new People(dataset_y, DataFactory)

    for (const person of people) {
    console.log(person.name)
    }
    // outputs
    // Alice
    // Bob

    For example you can write a Person class with one name and one mum property:

    import { TermWrapper, LiteralAs, LiteralFrom, TermAs, TermFrom } from "https://unpkg.com/@rdfjs/wrapper"

    class Person extends TermWrapper {
    get name() {
    return this.singularNullable("https://example.org/name", LiteralAs.string)
    }

    set name(value) {
    this.singularNullable("https://example.org/name", value, LiteralFrom.string)
    }

    get mum() {
    return this.singularNullable("https://example.org/mum", TermAs.instance(Person))
    }

    set mum(value) {
    this.overwriteNullable("https://example.org/mum", value, TermFrom.instance)
    }
    }

    Assuming the following RDF has been loaded in a dataset dataset_z:

    PREFIX ex: <https://example.org/>

    ex:person1 ex:name "Alice" .

    ex:person2
    ex:name "Bob" ;
    ex:mum ex:person2 ;
    .

    Class usage:

    const person2 = new Person("https://example.org/person2", dataset_z, DataFactory)

    // Get property
    console.log(person2.name)
    // outputs "Bob"

    // Get property from child class
    console.log(person2.mum.name)
    // outputs "Alice"

    // Set class properties
    const person3 = new Person("https://example.org/person3", dataset_z, DataFactory)
    person3.name = "Joanne"
    person1.mum = person3
    console.log(person1.mum.name)
    // outputs "Joanne"
    console.log(person2.mum.mum.name)
    // outputs "Joanne"

    RDF/JS Wrapper uses the interfaces described in the RDF/JS specifications.

    Practically, to map RDF to objects, you need to:

    1. Write a class or use an existing class that extends TermWrapper
    2. Each class needs a Term, a Dataset, and a DataFactory to be instantiated
    3. Each class property will have an associated www.w3.org/TR/rdf11-schema/#ch_properties (a string, generally a URL, that is defined by an ontology/vocabulary)
    4. Each class property will have an associated arity (singular, singular nullable or set)
    5. Each class property depending on its type can have:
      1. a corresponding value mapping to get values, that is translating RDF Terms to JavaScript primitive values (string, number, boolean...)
      2. a corresponding term mapping to set values, that is translating Javascript primitive values to RDF Terms
      3. a corresponding mapping to wrap child objects as a TermWrapper
      4. a corresponding mapping for sets of primitive values
    6. Each class mutates the underlying Dataset that is passed to it at instantiation time
    1. Run npm version major | minor | patch locally (see npm-version)
    2. Draft a new release
    3. The Continuous Deployment action will be triggered and automatically publish to npm

    This work is dual-licensed under MIT and Apache 2.0. You can choose between one of them if you use this work.

    SPDX-License-Identifier: MIT OR Apache-2.0