npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

oxigraph

v0.4.4

Published

JavaScript bindings of Oxigraph

Downloads

7,486

Readme

Oxigraph for JavaScript

npm actions status Gitter

This package provides a JavaScript API on top of Oxigraph, compiled with WebAssembly.

Oxigraph is a graph database written in Rust implementing the SPARQL standard.

Oxigraph for JavaScript is a work in progress and currently offers a simple in-memory store with SPARQL 1.1 Query and SPARQL 1.1 Update capabilities.

The store is also able to load RDF serialized in Turtle, TriG, N-Triples, N-Quads and RDF/XML.

It is distributed using a a NPM package that should work with Node.JS 18+ and modern web browsers compatible with WebAssembly reference types and JavaScript WeakRef.

To install:

npm install oxigraph

To load with Node.JS:

const oxigraph = require('oxigraph');

or with ES modules:

import oxigraph from './node_modules/oxigraph/node.js';

To load on an HTML web page (for WebPack 5 remove the <script> tag and put the code in a JS file):

<script type="module">
    import init, * as oxigraph from './node_modules/oxigraph/web.js'

    (async function () {
        await init(); // Required to compile the WebAssembly code.

        // We can use here Oxigraph methods
    })()
</script>

Node.JS Example

Insert the triple <http://example/> <http://schema.org/name> "example" and log the name of <http://example/> in SPARQL:

const oxigraph = require('oxigraph');
const store = new oxigraph.Store();
const ex = oxigraph.namedNode("http://example/");
const schemaName = oxigraph.namedNode("http://schema.org/name");
store.add(oxigraph.triple(ex, schemaName, oxigraph.literal("example")));
for (const binding of store.query("SELECT ?name WHERE { <http://example/> <http://schema.org/name> ?name }")) {
    console.log(binding.get("name").value);
}

Web Example

Insert the triple <http://example/> <http://schema.org/name> "example" and log the name of <http://example/> in SPARQL:


<script type="module">
    import init, * as oxigraph from './node_modules/oxigraph/web.js'

    (async function () {
        await init(); // Required to compile the WebAssembly.

        const store = new oxigraph.Store();
        const ex = oxigraph.namedNode("http://example/");
        const schemaName = oxigraph.namedNode("http://schema.org/name");
        store.add(oxigraph.triple(ex, schemaName, oxigraph.literal("example")));
        for (const binding of store.query("SELECT ?name WHERE { <http://example/> <http://schema.org/name> ?name }")) {
            console.log(binding.get("name").value);
        }
    })()
</script>

This example works with WebPack too if you remove the <script> tag and put the code in a JS file.

API

Oxigraph currently provides a simple JS API.

RDF data model

Oxigraph implements the RDF/JS datamodel specification.

For that, the oxigraph module implements the RDF/JS DataFactory interface.

Example:

const oxigraph = require('oxigraph');
const ex = oxigraph.namedNode("http://example.com");
const blank = oxigraph.blankNode();
const foo = oxigraph.literal("foo");
const quad = oxigraph.quad(blank, ex, foo);

All terms overrides the the toString() method to return a N-Quads/SPARQL-like representation of the terms.

Store

Oxigraph API is centered around the Store class.

A store contains an RDF dataset and allows to query and update them using SPARQL.

Store(optional sequence<Quad>? quads) (constructor)

Creates a new store.

const oxigraph = require('oxigraph');
const store = new oxigraph.Store();

If provided, the Store will be initialized with a sequence of quads.

const oxigraph = require('oxigraph');
const store = new oxigraph.Store([oxigraph.quad(blank, ex, foo)]);

Store.prototype.add(Quad quad)

Inserts a quad in the store.

Example:

store.add(quad);

Store.prototype.delete(Quad quad)

Removes a quad from the store.

Example:

store.delete(quad);

Store.prototype.has(Quad quad)

Returns a boolean stating if the store contains the quad.

Example:

store.has(quad);

Store.prototype.match(optional Term? subject, optional Term? predicate, optional Term? object, optional Term? graph)

Returns an array with all the quads matching a given quad pattern.

Example to get all quads in the default graph with ex for subject:

store.match(ex, null, null, oxigraph.defaultGraph());

Example to get all quads:

store.match();

Store.prototype.query(String query, object options)

Executes a SPARQL 1.1 Query. For SELECT queries the return type is an array of Map which keys are the bound variables and values are the values the result is bound to. For CONSTRUCT and ÐESCRIBE queries the return type is an array of Quad. For ASK queries the return type is a boolean.

Example of SELECT query:

for (binding of store.query("SELECT DISTINCT ?s WHERE { ?s ?p ?o }")) {
    console.log(binding.get("s").value);
}

Example of CONSTRUCT query:

const filteredStore = new oxigraph.Store(store.query("CONSTRUCT { <http:/example.com/> ?p ?o } WHERE { <http:/example.com/> ?p ?o }"));

Example of ASK query:

if (store.query("ASK { ?s ?s ?s }")) {
    console.log("there is a triple with same subject, predicate and object");
}

It is also possible to provide some options in an object given as second argument:

console.log(store.query("ASK { <s> ?p ?o }", {
  base_iri: "http://example.com/", // base IRI to resolve relative IRIs in the query
  use_default_graph_as_union: true, // the default graph in the query is the union of all the dataset graphs
  default_graph: [oxigraph.defaultGraph(), oxigraph.namedNode("http://example.com")], // the default graph of the query is the union of the store default graph and the http://example.com graph
  named_graphs: [oxigraph.namedNode("http://example.com"), oxigraph.blankNode("b")], // we restrict the available named graphs to the two listed
  results_format: "json", // the response will be serialized a string in the JSON format (media types like application/sparql-results+json also work)
}));

Store.prototype.update(String query, object options)

Executes a SPARQL 1.1 Update. The LOAD operation is not supported yet.

Example of update:

store.update("DELETE WHERE { <http://example.com/s> ?p ?o }")

It is also possible to provide some options in an object given as second argument:

store.update("DELETE WHERE { <s> ?p ?o }", {
  base_iri: "http://example.com/" // base IRI to resolve relative IRIs in the update
})

Store.prototype.load(String data, object options)

Loads serialized RDF triples or quad into the store. The method arguments are:

  1. data: the serialized RDF triples or quads.
  2. options: an object containing various options (all optional except format):
    • format: the format of the serialization as a string. See below for the supported formats.
    • base_iri: the base IRI to use to resolve the relative IRIs in the serialization as a string or a NamedNode.
    • to_named_graph: for triple serialization formats, the name of the named graph the triple should be loaded to as a NamedNode, BlankNode or DefaultGraph.
    • unchecked: disables careful data validation like checking if the IRIs or language tags are valid. Also automatically recovers from some small syntax errors.
    • no_transaction: disables transactional guarantees: if the file has a syntax error, the start of it might be loaded into the store even if parsing fails.

The available formats are:

  • Turtle: text/turtle or ttl
  • TriG: application/trig or trig
  • N-Triples: application/n-triples or nt
  • N-Quads: application/n-quads or nq
  • N3: text/n3 or n3
  • RDF/XML: application/rdf+xml or rdf

Example of loading a Turtle file into the named graph <http://example.com/graph> with the base IRI http://example.com:

store.load(
    "<http://example.com> <http://example.com> <> .",
    {
        format: "text/turtle",
        base_iri: "http://example.com",
        to_graph_name: oxigraph.namedNode("http://example.com/graph")
    }
);

Store.prototype.dump(object options)

Returns serialized RDF triples or quad from the store. The method argument is a single object, options, with the following options (all optional except format):

  • format: the format type of the serialization as a string. See below for the supported types.
  • from_named_graph: for triple serialization formats, the name of the named graph the triple should be loaded from as a NamedNode, BlankNode or DefaultGraph..

The available formats are:

  • Turtle: text/turtle or ttl
  • TriG: application/trig or trig
  • N-Triples: application/n-triples or nt
  • N-Quads: application/n-quads or nq
  • N3: text/n3 or n3
  • RDF/XML: application/rdf+xml or rdf

Example of building a Turtle file from the named graph <http://example.com/graph>:

store.dump({
    format: "text/turtle",
    from_graph_name: oxigraph.namedNode("http://example.com/graph")
});

Migration guide

From 0.2 to 0.3

  • The MemoryStore class is now called Store (there is no other kind of stores...).
  • RDF/JS datamodel functions (namedNode...) are now available at the root of the oxigraph package. You now need to call oxigraph.namedNode instead of store.dataFactory.namedNode.
  • RDF-star is now implemented. Quad is now a valid value for the Ωuad subject and object properties.

How to contribute

The Oxigraph bindings are written in Rust using the Rust WASM toolkit.

The The Rust Wasm Book is a great tutorial to get started.

To setup a dev environment:

  • ensure to have a Rust toolchain with rustup and cargo installed (possible instructions).
  • npm install to install JS dependencies.
  • you are good to go!

Testing and linting:

  • Rust code is formatted with rustfmt and linted with clippy. You can execute them with cargo fmt and cargo clippy.
  • JS code is formatted and linted with Biome. npm run fmt to auto-format and npm test to lint and test.
  • Tests are written in JavaScript using Mocha in the test directory. npm test to run them.

License

This project is licensed under either of

  • Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
  • MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in Oxigraph by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.