@unrdf/rdf-graphql 26.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,431 @@
1
+ # @unrdf/rdf-graphql
2
+
3
+ Type-safe GraphQL interface for RDF knowledge graphs with automatic schema generation from ontologies.
4
+
5
+ ## Overview
6
+
7
+ `@unrdf/rdf-graphql` automatically generates GraphQL schemas from RDF ontologies (RDFS/OWL) and provides type-safe query execution backed by the Oxigraph SPARQL engine. It bridges the semantic web and modern API development.
8
+
9
+ ## Features
10
+
11
+ - **Automatic Schema Generation**: Convert RDFS/OWL ontologies to GraphQL schemas
12
+ - **Type Safety**: Full type mapping from XSD datatypes to GraphQL scalars
13
+ - **SPARQL Translation**: GraphQL queries automatically translated to SPARQL
14
+ - **High Performance**: Powered by Oxigraph's native SPARQL engine
15
+ - **Query Caching**: Optional result caching for improved performance
16
+ - **Federation Support**: Designed for distributed knowledge graphs
17
+ - **Zero Configuration**: Works out-of-the-box with standard ontologies
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ pnpm add @unrdf/rdf-graphql @unrdf/oxigraph graphql
23
+ ```
24
+
25
+ ## Quick Start
26
+
27
+ ```javascript
28
+ import { createAdapter } from '@unrdf/rdf-graphql';
29
+
30
+ // Create adapter with namespace configuration
31
+ const adapter = createAdapter({
32
+ namespaces: {
33
+ ex: 'http://example.org/schema#',
34
+ },
35
+ enableCache: true,
36
+ });
37
+
38
+ // Load RDF ontology (defines schema)
39
+ const ontology = `
40
+ @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
41
+ @prefix ex: <http://example.org/schema#> .
42
+ @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
43
+
44
+ ex:Person a rdfs:Class ;
45
+ rdfs:label "Person" .
46
+
47
+ ex:name a rdf:Property ;
48
+ rdfs:domain ex:Person ;
49
+ rdfs:range xsd:string .
50
+
51
+ ex:age a rdf:Property ;
52
+ rdfs:domain ex:Person ;
53
+ rdfs:range xsd:integer .
54
+ `;
55
+
56
+ await adapter.loadOntology(ontology);
57
+
58
+ // Load instance data
59
+ const data = `
60
+ @prefix ex: <http://example.org/schema#> .
61
+
62
+ <http://example.org/people/alice> a ex:Person ;
63
+ ex:name "Alice Smith" ;
64
+ ex:age 30 .
65
+ `;
66
+
67
+ await adapter.loadData(data);
68
+
69
+ // Generate GraphQL schema
70
+ const schema = adapter.generateSchema();
71
+
72
+ // Execute GraphQL queries
73
+ const result = await adapter.executeQuery(`
74
+ query {
75
+ persons {
76
+ id
77
+ name
78
+ age
79
+ }
80
+ }
81
+ `);
82
+
83
+ console.log(result.data.persons);
84
+ // [{ id: "http://example.org/people/alice", name: "Alice Smith", age: 30 }]
85
+ ```
86
+
87
+ ## Ontology to GraphQL Mapping Rules
88
+
89
+ ### Class Mapping
90
+
91
+ | RDF/OWL | GraphQL | Example |
92
+ |---------|---------|---------|
93
+ | `rdfs:Class` | `ObjectType` | `ex:Person` → `type Person` |
94
+ | `owl:Class` | `ObjectType` | `owl:Thing` → `type Thing` |
95
+ | Class local name | Type name | `ex:WorkflowCase` → `WorkflowCase` |
96
+
97
+ ### Property Mapping
98
+
99
+ | RDF/OWL | GraphQL | Example |
100
+ |---------|---------|---------|
101
+ | `rdf:Property` | Field | `ex:name` → `name: String` |
102
+ | `rdfs:domain` | Parent type | `ex:Person` → field in `Person` |
103
+ | `rdfs:range` | Field type | `xsd:string` → `String` |
104
+ | `owl:ObjectProperty` | Object field | `ex:manager` → `manager: Person` |
105
+ | `owl:DatatypeProperty` | Scalar field | `ex:email` → `email: String` |
106
+
107
+ ### Datatype Mapping
108
+
109
+ | XSD Datatype | GraphQL Type |
110
+ |--------------|--------------|
111
+ | `xsd:string` | `String` |
112
+ | `xsd:integer`, `xsd:int`, `xsd:long` | `Int` |
113
+ | `xsd:decimal`, `xsd:float`, `xsd:double` | `Float` |
114
+ | `xsd:boolean` | `Boolean` |
115
+ | `xsd:dateTime`, `xsd:anyURI` | `String` |
116
+ | Unknown/Missing | `String` (fallback) |
117
+
118
+ ### Query Generation
119
+
120
+ For each class, two root query fields are automatically generated:
121
+
122
+ ```graphql
123
+ # Single item query
124
+ person(id: ID!): Person
125
+
126
+ # List query with pagination
127
+ persons(limit: Int, offset: Int): [Person]
128
+ ```
129
+
130
+ ### Field Resolution
131
+
132
+ | GraphQL Query | SPARQL Translation |
133
+ |---------------|-------------------|
134
+ | `{ id }` | `?s` (subject IRI) |
135
+ | `{ name }` | `?s ex:name ?name` |
136
+ | `{ age }` | `?s ex:age ?age` |
137
+ | Nested objects | Additional graph patterns |
138
+
139
+ ## YAWL Workflow Example
140
+
141
+ ```javascript
142
+ import { createWorkflowAdapter, EXAMPLE_QUERIES } from '@unrdf/rdf-graphql/examples/workflow-schema';
143
+
144
+ // Create adapter with YAWL ontology
145
+ const { adapter, schema } = await createWorkflowAdapter();
146
+
147
+ // Query workflows
148
+ const result = await adapter.executeQuery(
149
+ EXAMPLE_QUERIES.getWorkflow,
150
+ { id: 'http://example.org/workflows/order-fulfillment' }
151
+ );
152
+
153
+ console.log(result.data.workflow);
154
+ // {
155
+ // id: "http://example.org/workflows/order-fulfillment",
156
+ // workflowId: "wf-001",
157
+ // name: "Order Fulfillment",
158
+ // description: "Process customer orders..."
159
+ // }
160
+
161
+ // List cases with pagination
162
+ const cases = await adapter.executeQuery(
163
+ EXAMPLE_QUERIES.listCases,
164
+ { limit: 10, offset: 0 }
165
+ );
166
+
167
+ console.log(cases.data.cases);
168
+ ```
169
+
170
+ ## API Reference
171
+
172
+ ### RDFGraphQLAdapter
173
+
174
+ Main entry point for the library.
175
+
176
+ #### Constructor Options
177
+
178
+ ```javascript
179
+ {
180
+ namespaces: Record<string, string>, // Namespace prefixes
181
+ excludeClasses: string[], // Classes to exclude from schema
182
+ includeInferred: boolean, // Include inferred types (default: false)
183
+ enableCache: boolean, // Enable query result caching (default: false)
184
+ typeMapping: Record<string, string> // Custom GraphQL type to RDF class mapping
185
+ }
186
+ ```
187
+
188
+ #### Methods
189
+
190
+ **`loadOntology(rdfData, format?, baseIRI?)`**
191
+ Load RDF ontology defining the schema.
192
+
193
+ **`loadData(rdfData, format?, baseIRI?)`**
194
+ Load RDF instance data.
195
+
196
+ **`generateSchema(options?)`**
197
+ Generate GraphQL schema from loaded ontology.
198
+
199
+ **`executeQuery(query, variables?, context?)`**
200
+ Execute GraphQL query and return results.
201
+
202
+ **`executeSPARQL(query)`**
203
+ Execute SPARQL query directly against the store.
204
+
205
+ **`getSchema()`**
206
+ Get the generated GraphQL schema.
207
+
208
+ **`getStore()`**
209
+ Get the underlying Oxigraph store.
210
+
211
+ **`introspectClasses()`**
212
+ Get all classes in the ontology.
213
+
214
+ **`introspectProperties()`**
215
+ Get all properties in the ontology.
216
+
217
+ **`getStatistics()`**
218
+ Get store statistics (triple count, class count, instance count).
219
+
220
+ **`clearCache()`**
221
+ Clear query result cache.
222
+
223
+ **`getCacheStats()`**
224
+ Get cache statistics.
225
+
226
+ ### SPARQLQueryBuilder
227
+
228
+ Translates GraphQL queries to SPARQL.
229
+
230
+ ```javascript
231
+ import { SPARQLQueryBuilder } from '@unrdf/rdf-graphql/query';
232
+
233
+ const builder = new SPARQLQueryBuilder({
234
+ namespaces: {
235
+ ex: 'http://example.org/schema#',
236
+ },
237
+ });
238
+
239
+ // Add custom namespace
240
+ builder.addNamespace('custom', 'http://custom.org/');
241
+
242
+ // Build queries
243
+ const sparql = builder.buildListQuery(info, typeIRI, { limit: 10, offset: 0 });
244
+ ```
245
+
246
+ ### RDFSchemaGenerator
247
+
248
+ Generates GraphQL schemas from RDF ontologies.
249
+
250
+ ```javascript
251
+ import { RDFSchemaGenerator } from '@unrdf/rdf-graphql/schema';
252
+
253
+ const generator = new RDFSchemaGenerator({
254
+ namespaces: { ex: 'http://example.org/' },
255
+ excludeClasses: ['http://example.org/InternalClass'],
256
+ });
257
+
258
+ await generator.loadOntology(rdfData);
259
+ const schema = generator.generateSchema();
260
+ ```
261
+
262
+ ## Advanced Usage
263
+
264
+ ### Custom Type Mapping
265
+
266
+ ```javascript
267
+ const adapter = createAdapter({
268
+ namespaces: { yawl: 'http://example.org/yawl#' },
269
+ typeMapping: {
270
+ Workflow: 'http://example.org/yawl#Workflow',
271
+ Case: 'http://example.org/yawl#Case',
272
+ Task: 'http://example.org/yawl#Task',
273
+ },
274
+ });
275
+ ```
276
+
277
+ ### Query Caching
278
+
279
+ ```javascript
280
+ const adapter = createAdapter({
281
+ enableCache: true,
282
+ });
283
+
284
+ // ... execute queries ...
285
+
286
+ // Check cache stats
287
+ console.log(adapter.getCacheStats());
288
+ // { enabled: true, size: 42 }
289
+
290
+ // Clear cache
291
+ adapter.clearCache();
292
+ ```
293
+
294
+ ### Direct SPARQL Execution
295
+
296
+ ```javascript
297
+ const results = adapter.executeSPARQL(`
298
+ SELECT ?subject ?predicate ?object WHERE {
299
+ ?subject ?predicate ?object .
300
+ }
301
+ LIMIT 10
302
+ `);
303
+
304
+ console.log(results);
305
+ // [{ subject: "...", predicate: "...", object: "..." }, ...]
306
+ ```
307
+
308
+ ### Ontology Introspection
309
+
310
+ ```javascript
311
+ // Get all classes
312
+ const classes = adapter.introspectClasses();
313
+ console.log(classes);
314
+ // [{ iri: "...", label: "...", comment: "..." }, ...]
315
+
316
+ // Get all properties
317
+ const properties = adapter.introspectProperties();
318
+ console.log(properties);
319
+ // [{ iri: "...", domain: "...", range: "...", label: "..." }, ...]
320
+
321
+ // Get statistics
322
+ const stats = await adapter.getStatistics();
323
+ console.log(stats);
324
+ // { tripleCount: 1234, classCount: 10, instanceCount: 567 }
325
+ ```
326
+
327
+ ## Architecture
328
+
329
+ ```
330
+ ┌─────────────────────────────────────────────────────────┐
331
+ │ GraphQL Client │
332
+ └────────────────────┬────────────────────────────────────┘
333
+ │ GraphQL Query
334
+
335
+ ┌─────────────────────────────────────────────────────────┐
336
+ │ RDFGraphQLAdapter │
337
+ │ ┌────────────────┐ ┌──────────────────────────────┐ │
338
+ │ │ Schema │ │ Resolver Factory │ │
339
+ │ │ Generator │ │ (creates resolvers) │ │
340
+ │ └────────────────┘ └──────────────────────────────┘ │
341
+ └──────────┬──────────────────────┬───────────────────────┘
342
+ │ RDFS/OWL │ SPARQL
343
+ ▼ ▼
344
+ ┌──────────────────────┐ ┌──────────────────────────────┐
345
+ │ Ontology (Schema) │ │ SPARQLQueryBuilder │
346
+ │ - Classes │ │ (GraphQL → SPARQL) │
347
+ │ - Properties │ └──────────┬───────────────────┘
348
+ │ - Datatypes │ │ SPARQL Query
349
+ └──────────────────────┘ ▼
350
+ ┌──────────────────────────────┐
351
+ │ Oxigraph Store │
352
+ │ (RDF triple store) │
353
+ └──────────────────────────────┘
354
+ ```
355
+
356
+ ## Performance Considerations
357
+
358
+ 1. **Schema Generation**: One-time cost at startup
359
+ 2. **Query Translation**: Minimal overhead (< 1ms)
360
+ 3. **SPARQL Execution**: Depends on query complexity and data size
361
+ 4. **Caching**: Recommended for read-heavy workloads
362
+ 5. **Indexing**: Oxigraph automatically indexes RDF data
363
+
364
+ ## Federation (Future)
365
+
366
+ Designed for distributed knowledge graphs:
367
+
368
+ ```javascript
369
+ // Future API (not yet implemented)
370
+ const federatedAdapter = createFederatedAdapter({
371
+ services: [
372
+ { name: 'workflows', url: 'http://service1/graphql' },
373
+ { name: 'users', url: 'http://service2/graphql' },
374
+ ],
375
+ });
376
+ ```
377
+
378
+ ## Testing
379
+
380
+ ```bash
381
+ # Run all tests
382
+ pnpm test
383
+
384
+ # Run with timeout (recommended)
385
+ timeout 5s pnpm test
386
+ ```
387
+
388
+ ## Use Cases
389
+
390
+ 1. **Semantic Web APIs**: Expose RDF knowledge graphs via GraphQL
391
+ 2. **Workflow Systems**: Query YAWL workflows with type safety
392
+ 3. **Knowledge Management**: Type-safe access to ontology-based data
393
+ 4. **Data Integration**: Unified GraphQL interface for heterogeneous RDF sources
394
+ 5. **Research Data**: Query scientific datasets with GraphQL
395
+
396
+ ## Limitations
397
+
398
+ 1. **No Mutations**: Read-only (queries only, no mutations/subscriptions yet)
399
+ 2. **Simple Relationships**: Nested queries limited to one level
400
+ 3. **No Inference**: RDFS/OWL reasoning not yet implemented
401
+ 4. **Scalar Types**: Limited to XSD datatypes mapped in table above
402
+
403
+ ## Roadmap
404
+
405
+ - [ ] GraphQL mutations (INSERT/UPDATE/DELETE)
406
+ - [ ] Subscriptions for real-time updates
407
+ - [ ] RDFS/OWL inference support
408
+ - [ ] GraphQL federation support
409
+ - [ ] Custom scalar types
410
+ - [ ] Performance optimizations (query planning)
411
+ - [ ] GraphQL schema stitching
412
+
413
+ ## License
414
+
415
+ MIT
416
+
417
+ ## Contributing
418
+
419
+ Contributions welcome! Please ensure:
420
+ - All tests pass (`pnpm test`)
421
+ - Code follows existing patterns
422
+ - JSDoc comments for all public APIs
423
+ - No TypeScript in source (use JSDoc + Zod)
424
+
425
+ ## References
426
+
427
+ - [GraphQL Specification](https://spec.graphql.org/)
428
+ - [SPARQL 1.1 Query Language](https://www.w3.org/TR/sparql11-query/)
429
+ - [RDF Schema (RDFS)](https://www.w3.org/TR/rdf-schema/)
430
+ - [OWL Web Ontology Language](https://www.w3.org/TR/owl2-overview/)
431
+ - [Oxigraph Documentation](https://github.com/oxigraph/oxigraph)
@@ -0,0 +1,92 @@
1
+ # Capability Map: @unrdf/rdf-graphql
2
+
3
+ **Generated:** 2025-12-28
4
+ **Package:** @unrdf/rdf-graphql
5
+ **Version:** 1.0.0
6
+
7
+ ---
8
+
9
+ ## Description
10
+
11
+ Type-safe GraphQL interface for RDF knowledge graphs with automatic schema generation
12
+
13
+ ---
14
+
15
+ ## Capability Atoms
16
+
17
+ ### A58: GraphQL Schema Generation
18
+
19
+ **Runtime:** Node.js
20
+ **Invariants:** RDF-to-GraphQL mapping
21
+ **Evidence:** `packages/rdf-graphql/src/index.mjs`
22
+
23
+
24
+
25
+ ---
26
+
27
+ ## Package Metadata
28
+
29
+ ### Dependencies
30
+
31
+ - `graphql`: ^16.8.1
32
+ - `@graphql-tools/schema`: ^10.0.2
33
+ - `@unrdf/oxigraph`: workspace:*
34
+ - `zod`: ^3.22.4
35
+
36
+ ### Exports
37
+
38
+ - `.`: `./src/adapter.mjs`
39
+ - `./schema`: `./src/schema-generator.mjs`
40
+ - `./query`: `./src/query-builder.mjs`
41
+ - `./resolver`: `./src/resolver.mjs`
42
+
43
+ ---
44
+
45
+ ## Integration Patterns
46
+
47
+ ### Primary Use Cases
48
+
49
+ 1. **GraphQL Schema Generation**
50
+ - Import: `import { /* exports */ } from '@unrdf/rdf-graphql'`
51
+ - Use for: GraphQL Schema Generation operations
52
+ - Runtime: Node.js
53
+
54
+
55
+ ### Composition Examples
56
+
57
+ ```javascript
58
+ import { createStore } from '@unrdf/oxigraph';
59
+ import { /* functions */ } from '@unrdf/rdf-graphql';
60
+
61
+ const store = createStore();
62
+ // Use rdf-graphql capabilities with store
63
+ ```
64
+
65
+
66
+ ---
67
+
68
+ ## Evidence Trail
69
+
70
+ - **A58**: `packages/rdf-graphql/src/index.mjs`
71
+
72
+ ---
73
+
74
+ ## Next Steps
75
+
76
+ 1. **Explore API Surface**
77
+ - Review exports in package.json
78
+ - Read source files in `src/` directory
79
+
80
+ 2. **Integration Testing**
81
+ - Create test cases using package capabilities
82
+ - Verify compatibility with dependent packages
83
+
84
+ 3. **Performance Profiling**
85
+ - Benchmark key operations
86
+ - Measure runtime characteristics
87
+
88
+ ---
89
+
90
+ **Status:** GENERATED
91
+ **Method:** Systematic extraction from capability-basis.md + package.json analysis
92
+ **Confidence:** 95% (evidence-based)
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@unrdf/rdf-graphql",
3
+ "version": "26.4.2",
4
+ "description": "Type-safe GraphQL interface for RDF knowledge graphs with automatic schema generation",
5
+ "type": "module",
6
+ "main": "src/adapter.mjs",
7
+ "exports": {
8
+ ".": "./src/adapter.mjs",
9
+ "./schema": "./src/schema-generator.mjs",
10
+ "./query": "./src/query-builder.mjs",
11
+ "./resolver": "./src/resolver.mjs"
12
+ },
13
+ "scripts": {
14
+ "test": "node --test test/*.test.mjs",
15
+ "test:watch": "node --test --watch test/*.test.mjs",
16
+ "lint": "eslint src/**/*.mjs test/**/*.mjs"
17
+ },
18
+ "keywords": [
19
+ "rdf",
20
+ "graphql",
21
+ "sparql",
22
+ "ontology",
23
+ "knowledge-graph",
24
+ "semantic-web",
25
+ "type-safe"
26
+ ],
27
+ "dependencies": {
28
+ "graphql": "^16.8.1",
29
+ "@graphql-tools/schema": "^10.0.2",
30
+ "@unrdf/oxigraph": "workspace:*",
31
+ "zod": "^3.22.4"
32
+ },
33
+ "author": "UNRDF Team",
34
+ "license": "MIT"
35
+ }