Port-agnostic TypeScript library for RDF quad-store, SPARQL, and SHACL
validation operations. Wraps N3.js,
Comunica,
rdf-validate-shacl,
sparqljs, and
jsonld.js behind a single
QuadStoreSession class.
Originally extracted from
elm-qudt, where it backed the
in-browser RDF quad store via Elm ports. This package is the
port-agnostic core; the companion @ralphtq/rdf-n3-quads-elm-ports
shim adapts it for elm-pages / Elm apps.
Pre-release. 0.1.0 is the first publish; APIs may change before 1.0.0.
npm install @ralphtq/elm-rdf-n3-quadsYou also need the runtime peers:
npm install n3 @comunica/query-sparql rdf-validate-shacl sparqljs jsonld jszipimport { QuadStoreSession } from '@ralphtq/elm-rdf-n3-quads';
const session = new QuadStoreSession();
const { ticket, dataModel } = await session.parseTTL(turtleContent, baseIRI);
// `ticket` mirrors what Elm consumes via the `quadStoreUpdated` port today;
// `dataModel` is the JSON wire shape used by the elm-pages app.
const results = await session.query('SELECT ?s WHERE { ?s ?p ?o } LIMIT 10');
const turtle = await session.writeTurtle(quads);
const jsonld = await session.writeJSONLD(quads);
const report = await session.validateSHACL({ dataGraphContent, shapesGraphContent });Every method returns a Promise. There is no port awareness, no app
parameter, no app.ports.X.send() calls anywhere in the package.
rdf-utils — term/quad conversion, IRI shortening, CURIE expansionsparql-format — pretty-print SPARQL via sparqljsrdf-writers — Turtle (TriG) and JSON-LD serializationn3-parser — N3/TTL parsing into the session's N3.Storen3-query — SPARQL execution via Comunicaschema-resources-query — typed-resource discoveryshape-parser — SHACL shape collection parsingshacl-validator — SHACL validation (JS engine via rdf-validate-shacl)sparql-constraint-validator — sh:sparql constraint handlingshacl-functions — SHACL extension functions (sh:ask, sh:select)zip-catalog — ZIP file catalog and content extractioninference-runner — SHACL inference transformsQuadStoreSession — central façade owning the N3.Store and Comunica QueryEngineThe Jena SHACL bridge lives in a separate package
(@ralphtq/elm-rdf-jena, forthcoming) to keep this package
browser-friendly and Node-dep-free.
npm install
npm run build # tsc -> dist/
npm test # vitest run
npm run typecheck # tsc --noEmitMIT. See LICENSE.
This repo also publishes an Elm package
(ralphtq/elm-rdf-n3-quads) that mirrors the JSON wire format the
TypeScript side produces. If you're consuming this package from an
Elm / elm-pages app, the Elm package gives you decoders for the JSON
that arrives over ports — so your Elm code never has to re-derive the
wire shape and drift cannot creep in undetected.
import Rdf.Wire.Types exposing (JSONdataModel)
import Rdf.Wire.Decode
port receiveJSONdataModelV2 : (Json.Decode.Value -> msg) -> Sub msg
subscriptions =
receiveJSONdataModelV2 <|
\value ->
case Json.Decode.decodeValue Rdf.Wire.Decode.jsonDataModel value of
Ok payload -> GotDataModel payload
Err err -> DecodeFailed (Json.Decode.errorToString err)Install with elm install ralphtq/elm-rdf-n3-quads (or copy the
modules directly from this repo until v0.1.0 publishes to the Elm
package registry).
A cross-language fixture (tests/fixtures/sample-data-model.json)
serves as the source of truth for the wire shape — both the Elm
test suite (elm-test) and the vitest TypeScript suite read it,
so any drift in either ecosystem trips a test in CI.
0.1.0, 0.1.1, ... → Elm package releases (bare semver, per elm publish).v0.3.0, v0.3.1, ... → npm package releases (with v prefix).The two tag streams coexist in this repo without colliding.
npx elm-test # run the Elm test suite (tests/*.elm)
npx elm-format --validate src tests