Skip to content

feat: add named graph wrapping functionality - #62

Merged
langsamu merged 8 commits into
mainfrom
feat/named-graph-selector
Apr 15, 2026
Merged

feat: add named graph wrapping functionality#62
langsamu merged 8 commits into
mainfrom
feat/named-graph-selector

Conversation

@jeswr

@jeswr jeswr commented Apr 13, 2026

Copy link
Copy Markdown
Member

@langsamu this PR is ready for review

Partially resolves #43

This PR introduces namedGraph function which creates a DatasetCore view over a single named graph, projecting its contents into the default graph. This lets you use any existing TermWrapper or DatasetWrapper classes unchanged, scoped to a specific graph.

import { namedGraph, DatasetWrapper, TermWrapper, LiteralAs, OptionalFrom } from "@rdfjs/wrapper"

// Given a dataset with quads in a named graph:
// <ex:person1> <ex:name> "Alice" <ex:graph1> .
// <ex:person2> <ex:name> "Bob" <ex:graph1> .
// <ex:person1> <ex:name> "Charlie" .                  (default graph)

const graphView = namedGraph("https://example.org/graph1", dataset, DataFactory)

// graphView behaves as a DatasetCore containing only default graph quads:
// <ex:person1> <ex:name> "Alice" .
// <ex:person2> <ex:name> "Bob" .

// Wrap it with your existing classes:
class People extends DatasetWrapper {
    get all() {
        return this.subjectsOf("https://example.org/name", Person)
    }
}

const people = new People(graphView, DataFactory)
for (const person of people.all) {
    console.log(person.name)
}
// outputs "Alice", "Bob"  (Charlie is excluded — different graph)

Writes through the view are mapped back to the named graph in the underlying dataset:

// Adding a quad through the view stores it in the named graph
graphView.add(DataFactory.quad(s, p, o))
// Equivalent to: dataset.add(DataFactory.quad(s, p, o, DataFactory.namedNode("https://example.org/graph1")))

Any attempt to use a non-default graph on the returned DatasetCore throws a NamedGraphError:

// These all throw NamedGraphError:
graphView.add(DataFactory.quad(s, p, o, DataFactory.namedNode("https://other.org/g")))
graphView.match(undefined, undefined, undefined, DataFactory.namedNode("https://other.org/g"))

Copilot AI review requested due to automatic review settings April 13, 2026 13:59
Comment thread test/unit/named_graph_integration.test.ts Fixed
…tion or class'

Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a namedGraph utility that exposes a DatasetCore view of a single named graph as default-graph quads, enabling existing TermWrapper/DatasetWrapper usage scoped to a graph.

Changes:

  • Introduces namedGraph() and a NamedGraphDataset implementation that projects one named graph into the default graph and maps writes back.
  • Adds NamedGraphError and exports it along with namedGraph from the package entrypoint.
  • Adds unit + integration tests and documents the feature in the README.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/namedGraph.ts Implements the named-graph-to-default-graph dataset view and write-through behavior.
src/errors/NamedGraphError.ts Defines the error thrown when callers try to use non-default graphs on the view.
src/mod.ts Exports namedGraph and NamedGraphError from the public module.
test/unit/named_graph.test.ts Unit tests for projection, size, has, add/delete, and error cases.
test/unit/named_graph_integration.test.ts Integration tests verifying compatibility with TermWrapper/DatasetWrapper patterns.
README.md Adds documentation and examples for the new named graph view feature.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/namedGraph.ts Outdated
Comment thread src/namedGraph.ts Outdated
Comment thread README.md Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@jeswr

jeswr commented Apr 13, 2026

Copy link
Copy Markdown
Member Author

@copilot rather than implementing #62 (comment) -- support only Quad_Graphs as input to namedGraph and the associated class.

Copilot AI commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

@copilot rather than implementing #62 (comment) -- support only Quad_Graphs as input to namedGraph and the associated class.

Changed namedGraph and NamedGraphDataset to accept Quad_Graph instead of Term | string. Removed string coercion logic, updated tests and README examples accordingly. See 6185daf.

@jeswr

This comment was marked as duplicate.

@jeswr

This comment was marked as duplicate.

1 similar comment
@jeswr

jeswr commented Apr 13, 2026

Copy link
Copy Markdown
Member Author

@copilot please do implement caching as suggested in #62 (comment) - make sure this cache is cleared when an update operation takes place.

Copilot AI commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

@copilot please do implement caching as suggested in #62 (comment) - make sure this cache is cleared when an update operation takes pl...

Implemented caching via a graphView getter that lazily calls dataset.match() using ??=. The cache is invalidated on both add and delete operations. See adf7d61.

@jeswr

jeswr commented Apr 13, 2026

Copy link
Copy Markdown
Member Author

@langsamu this PR is ready for review

@langsamu langsamu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lovely addition.
I have reworked it in #63 (leaving the fundamental feature intact):

  • No caching. There is no caching anywhere else, so let's not start now. It's unrelated to the new feature, irrelevant, untested and premature.
  • Your function namedGraph is now a member of the existing DatasetWrapper, where we already have an underlying DatasetCore and a DataFactory. But most importantly, a DatasetWrapper is where I imagine most people will start their mapping and traversal journey, so I'd like all navigation to start there.
  • I've made your class NamedGraphDataset public and a subclass of DatasetWrapper, because that is what it is. Might as well enjoy the benefits. No functional changes there.
  • The new utility method DatasetWrapper#named returns a subclass of the above. This is how we maintain the context (underlying dataset and factory) as we traverse graph patterns down the property chain. We still want to wrap on top of (inside of) the named graph projection.
  • Made some minor changes to the guards and errors so they're aligned with the rest of the codebase.

@jaxoncreed

Copy link
Copy Markdown

Could we make a version that writes to a specific graph but reads from all graphs?

I'm happy to help given we agree on an interface.

langsamu
langsamu previously approved these changes Apr 15, 2026

@langsamu langsamu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest we merge and leave documentation improvements for later.

@matthieubosquet matthieubosquet left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to go.

@langsamu
langsamu merged commit 3167d3e into main Apr 15, 2026
11 checks passed
@langsamu
langsamu deleted the feat/named-graph-selector branch April 15, 2026 11:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Graph and Language Support

6 participants