Skip to main content
The WorldsSdk facade does not care which engine answers SPARQL. The sparqlEngine option accepts any implementation of SparqlEngineInterface.

Which path?

Built-in engine (zero config)

If you have an RDF/JS Store, the built-in engine covers SPARQL 1.1 & 1.2 with timeout and abort handling — no adapter needed:
MemoryStore is the engine’s built-in RDF/JS store with full SPARQL Update support (addQuad/removeQuad). If you use a different store (e.g. N3’s Store), it must also support addQuad/removeQuad for UPDATE queries, or you can pass a createTransaction factory for atomic writes. Skip the rest of this guide unless you need a different engine.

Custom engine (this guide)

If you need Comunica’s federation, actor system, or query-planning features, implement the interface yourself. It is a single method.

The contract

SparqlEngineInterface (defined in @wazoo/sparql-engine) has one method:
  • SparqlRequest carries query, baseIri?, timeoutMs?, and signal? (an AbortSignal the caller uses to cancel an in-flight request).
  • SparqlResponse is one of four shapes: { kind: "select", data }, { kind: "ask", data }, { kind: "construct", data }, or { kind: "void" }.
The types (SparqlEngineInterface, SparqlRequest, SparqlResponse, SparqlValue, etc.) are defined in @wazoo/sparql-engine and re-exported through @worlds/sdk/sparql-engine for SDK consumers. If you are implementing an engine, import from @wazoo/sparql-engine directly.

Install

Comunica and its RDF/JS types are npm packages. The types and term converter come from the Wazoo SPARQL engine:

Implement the interface

The adapter runs Comunica over the same RDF/JS store the quad facade uses, so imports and SPARQL queries see one consistent dataset. Comunica returns raw RDF/JS terms in async streams. The SparqlEngineInterface expects SPARQL JSON results format. The rdfTermToSparqlValue function from @wazoo/sparql-engine handles the conversion (including RDF 1.2 directional language-tagged literals).
comunica-sparql-engine.ts
That is the complete adapter — about 50 lines. The key pieces:
  • execute / #runexecute is the interface entry point; #run holds the Comunica call plus result mapping so the timeout/abort wiring below can wrap it.
  • rdfTermToSparqlValue (imported, not reimplemented) converts each RDF/JS binding term into the SparqlValue wire format the interface expects.
  • #select reads Comunica’s variable metadata to get the column names, then iterates the async bindings stream and builds SparqlBinding[].
  • #boolean, #quads, and void are one-liners that delegate to Comunica’s execute().

Adding timeout and abort support

The SparqlRequest carries timeoutMs and an AbortSignal. To honour them, compose one AbortController that fires on whichever comes first, then race the engine work against a promise that rejects when that controller aborts. The race is what hands control back to your caller; without it, a fired timer or caller abort would change nothing and queries would run to completion:
This is generic wiring, not Comunica-specific — the same pattern applies to any custom engine, and the built-in WazooSparqlEngine implements exactly this compose-and-race shape out of the box.

Wire it into a client

Swap the engine in the same way you would configure any other SparqlEngineInterface:
index.ts
The engine handles SELECT, ASK, CONSTRUCT/DESCRIBE, and SPARQL UPDATE, maps binding terms into the standard SPARQL results JSON shape, and (with the timeout/abort section above) honours timeoutMs and signal exactly as the interface documents.

Notes

  • Import from @wazoo/sparql-engine, not @worlds/sdk. The SDK re-exports the types for convenience (@worlds/sdk/sparql-engine), but @wazoo/sparql-engine is where they are defined. Engine implementors should depend on @wazoo/sparql-engine directly — it gives you the interface, the types, and rdfTermToSparqlValue in one import.
  • Transactional updates. Comunica writes directly to the store. If your backend needs atomic writes through its own transaction (like the built-in engine’s createTransaction), wrap the read store in a TransactionalRdfjsStore from @worlds/sdk/quad-store, hand that to the engine, and commit on void responses.
  • When to stay on Wazoo. The built-in WazooSparqlEngine is zero-dependency and covers SPARQL 1.1 & 1.2 for in-process RDF/JS stores. Reach for a custom engine when you need capabilities it does not provide — for example Comunica’s federation or actor customization.
  • No SDK changes needed. The adapter lives entirely in your project; the Worlds SDK only defines the interface.