@_linked/core 1.0.0 → 1.2.0-next.20260302120536

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.
Files changed (187) hide show
  1. package/CHANGELOG.md +72 -0
  2. package/README.md +321 -43
  3. package/lib/cjs/index.js +4 -0
  4. package/lib/cjs/index.js.map +1 -1
  5. package/lib/cjs/interfaces/IQuadStore.d.ts +19 -7
  6. package/lib/cjs/queries/CreateQuery.d.ts +7 -8
  7. package/lib/cjs/queries/CreateQuery.js +4 -4
  8. package/lib/cjs/queries/CreateQuery.js.map +1 -1
  9. package/lib/cjs/queries/DeleteQuery.d.ts +7 -8
  10. package/lib/cjs/queries/DeleteQuery.js +4 -4
  11. package/lib/cjs/queries/DeleteQuery.js.map +1 -1
  12. package/lib/cjs/queries/IRAliasScope.d.ts +20 -0
  13. package/lib/cjs/queries/IRAliasScope.js +52 -0
  14. package/lib/cjs/queries/IRAliasScope.js.map +1 -0
  15. package/lib/cjs/queries/IRCanonicalize.d.ts +36 -0
  16. package/lib/cjs/queries/IRCanonicalize.js +121 -0
  17. package/lib/cjs/queries/IRCanonicalize.js.map +1 -0
  18. package/lib/cjs/queries/IRDesugar.d.ts +98 -0
  19. package/lib/cjs/queries/IRDesugar.js +244 -0
  20. package/lib/cjs/queries/IRDesugar.js.map +1 -0
  21. package/lib/cjs/queries/IRLower.d.ts +8 -0
  22. package/lib/cjs/queries/IRLower.js +272 -0
  23. package/lib/cjs/queries/IRLower.js.map +1 -0
  24. package/lib/cjs/queries/IRMutation.d.ts +23 -0
  25. package/lib/cjs/queries/IRMutation.js +77 -0
  26. package/lib/cjs/queries/IRMutation.js.map +1 -0
  27. package/lib/cjs/queries/IRPipeline.d.ts +8 -0
  28. package/lib/cjs/queries/IRPipeline.js +25 -0
  29. package/lib/cjs/queries/IRPipeline.js.map +1 -0
  30. package/lib/cjs/queries/IRProjection.d.ts +38 -0
  31. package/lib/cjs/queries/IRProjection.js +98 -0
  32. package/lib/cjs/queries/IRProjection.js.map +1 -0
  33. package/lib/cjs/queries/IntermediateRepresentation.d.ts +210 -0
  34. package/lib/cjs/queries/IntermediateRepresentation.js +3 -0
  35. package/lib/cjs/queries/IntermediateRepresentation.js.map +1 -0
  36. package/lib/cjs/queries/MutationQuery.js +9 -23
  37. package/lib/cjs/queries/MutationQuery.js.map +1 -1
  38. package/lib/cjs/queries/QueryFactory.d.ts +0 -2
  39. package/lib/cjs/queries/QueryFactory.js +0 -3
  40. package/lib/cjs/queries/QueryFactory.js.map +1 -1
  41. package/lib/cjs/queries/QueryParser.d.ts +6 -1
  42. package/lib/cjs/queries/QueryParser.js +14 -22
  43. package/lib/cjs/queries/QueryParser.js.map +1 -1
  44. package/lib/cjs/queries/SelectQuery.d.ts +18 -27
  45. package/lib/cjs/queries/SelectQuery.js +54 -45
  46. package/lib/cjs/queries/SelectQuery.js.map +1 -1
  47. package/lib/cjs/queries/UpdateQuery.d.ts +8 -9
  48. package/lib/cjs/queries/UpdateQuery.js +4 -4
  49. package/lib/cjs/queries/UpdateQuery.js.map +1 -1
  50. package/lib/cjs/shapes/SHACL.d.ts +1 -0
  51. package/lib/cjs/shapes/SHACL.js +82 -2
  52. package/lib/cjs/shapes/SHACL.js.map +1 -1
  53. package/lib/cjs/shapes/Shape.d.ts +11 -10
  54. package/lib/cjs/shapes/Shape.js +11 -5
  55. package/lib/cjs/shapes/Shape.js.map +1 -1
  56. package/lib/cjs/sparql/SparqlAlgebra.d.ts +158 -0
  57. package/lib/cjs/sparql/SparqlAlgebra.js +4 -0
  58. package/lib/cjs/sparql/SparqlAlgebra.js.map +1 -0
  59. package/lib/cjs/sparql/SparqlStore.d.ts +52 -0
  60. package/lib/cjs/sparql/SparqlStore.js +81 -0
  61. package/lib/cjs/sparql/SparqlStore.js.map +1 -0
  62. package/lib/cjs/sparql/algebraToString.d.ts +13 -0
  63. package/lib/cjs/sparql/algebraToString.js +298 -0
  64. package/lib/cjs/sparql/algebraToString.js.map +1 -0
  65. package/lib/cjs/sparql/index.d.ts +9 -0
  66. package/lib/cjs/sparql/index.js +40 -0
  67. package/lib/cjs/sparql/index.js.map +1 -0
  68. package/lib/cjs/sparql/irToAlgebra.d.ts +39 -0
  69. package/lib/cjs/sparql/irToAlgebra.js +927 -0
  70. package/lib/cjs/sparql/irToAlgebra.js.map +1 -0
  71. package/lib/cjs/sparql/resultMapping.d.ts +36 -0
  72. package/lib/cjs/sparql/resultMapping.js +501 -0
  73. package/lib/cjs/sparql/resultMapping.js.map +1 -0
  74. package/lib/cjs/sparql/sparqlUtils.d.ts +32 -0
  75. package/lib/cjs/sparql/sparqlUtils.js +89 -0
  76. package/lib/cjs/sparql/sparqlUtils.js.map +1 -0
  77. package/lib/cjs/test-helpers/FusekiStore.d.ts +29 -0
  78. package/lib/cjs/test-helpers/FusekiStore.js +82 -0
  79. package/lib/cjs/test-helpers/FusekiStore.js.map +1 -0
  80. package/lib/cjs/test-helpers/fuseki-test-store.d.ts +43 -0
  81. package/lib/cjs/test-helpers/fuseki-test-store.js +144 -0
  82. package/lib/cjs/test-helpers/fuseki-test-store.js.map +1 -0
  83. package/lib/cjs/test-helpers/query-capture-store.d.ts +5 -0
  84. package/lib/cjs/test-helpers/query-capture-store.js +59 -0
  85. package/lib/cjs/test-helpers/query-capture-store.js.map +1 -0
  86. package/lib/cjs/test-helpers/query-fixtures.d.ts +700 -117
  87. package/lib/cjs/test-helpers/query-fixtures.js +39 -1
  88. package/lib/cjs/test-helpers/query-fixtures.js.map +1 -1
  89. package/lib/cjs/utils/LinkedStorage.d.ts +7 -7
  90. package/lib/cjs/utils/LinkedStorage.js +4 -3
  91. package/lib/cjs/utils/LinkedStorage.js.map +1 -1
  92. package/lib/esm/index.js +4 -0
  93. package/lib/esm/index.js.map +1 -1
  94. package/lib/esm/interfaces/IQuadStore.d.ts +19 -7
  95. package/lib/esm/queries/CreateQuery.d.ts +7 -8
  96. package/lib/esm/queries/CreateQuery.js +4 -4
  97. package/lib/esm/queries/CreateQuery.js.map +1 -1
  98. package/lib/esm/queries/DeleteQuery.d.ts +7 -8
  99. package/lib/esm/queries/DeleteQuery.js +4 -4
  100. package/lib/esm/queries/DeleteQuery.js.map +1 -1
  101. package/lib/esm/queries/IRAliasScope.d.ts +20 -0
  102. package/lib/esm/queries/IRAliasScope.js +47 -0
  103. package/lib/esm/queries/IRAliasScope.js.map +1 -0
  104. package/lib/esm/queries/IRCanonicalize.d.ts +36 -0
  105. package/lib/esm/queries/IRCanonicalize.js +116 -0
  106. package/lib/esm/queries/IRCanonicalize.js.map +1 -0
  107. package/lib/esm/queries/IRDesugar.d.ts +98 -0
  108. package/lib/esm/queries/IRDesugar.js +240 -0
  109. package/lib/esm/queries/IRDesugar.js.map +1 -0
  110. package/lib/esm/queries/IRLower.d.ts +8 -0
  111. package/lib/esm/queries/IRLower.js +268 -0
  112. package/lib/esm/queries/IRLower.js.map +1 -0
  113. package/lib/esm/queries/IRMutation.d.ts +23 -0
  114. package/lib/esm/queries/IRMutation.js +71 -0
  115. package/lib/esm/queries/IRMutation.js.map +1 -0
  116. package/lib/esm/queries/IRPipeline.d.ts +8 -0
  117. package/lib/esm/queries/IRPipeline.js +21 -0
  118. package/lib/esm/queries/IRPipeline.js.map +1 -0
  119. package/lib/esm/queries/IRProjection.d.ts +38 -0
  120. package/lib/esm/queries/IRProjection.js +92 -0
  121. package/lib/esm/queries/IRProjection.js.map +1 -0
  122. package/lib/esm/queries/IntermediateRepresentation.d.ts +210 -0
  123. package/lib/esm/queries/IntermediateRepresentation.js +2 -0
  124. package/lib/esm/queries/IntermediateRepresentation.js.map +1 -0
  125. package/lib/esm/queries/MutationQuery.js +9 -23
  126. package/lib/esm/queries/MutationQuery.js.map +1 -1
  127. package/lib/esm/queries/QueryFactory.d.ts +0 -2
  128. package/lib/esm/queries/QueryFactory.js +0 -3
  129. package/lib/esm/queries/QueryFactory.js.map +1 -1
  130. package/lib/esm/queries/QueryParser.d.ts +6 -1
  131. package/lib/esm/queries/QueryParser.js +14 -23
  132. package/lib/esm/queries/QueryParser.js.map +1 -1
  133. package/lib/esm/queries/SelectQuery.d.ts +18 -27
  134. package/lib/esm/queries/SelectQuery.js +54 -45
  135. package/lib/esm/queries/SelectQuery.js.map +1 -1
  136. package/lib/esm/queries/UpdateQuery.d.ts +8 -9
  137. package/lib/esm/queries/UpdateQuery.js +4 -4
  138. package/lib/esm/queries/UpdateQuery.js.map +1 -1
  139. package/lib/esm/shapes/SHACL.d.ts +1 -0
  140. package/lib/esm/shapes/SHACL.js +82 -2
  141. package/lib/esm/shapes/SHACL.js.map +1 -1
  142. package/lib/esm/shapes/Shape.d.ts +11 -10
  143. package/lib/esm/shapes/Shape.js +11 -5
  144. package/lib/esm/shapes/Shape.js.map +1 -1
  145. package/lib/esm/sparql/SparqlAlgebra.d.ts +158 -0
  146. package/lib/esm/sparql/SparqlAlgebra.js +3 -0
  147. package/lib/esm/sparql/SparqlAlgebra.js.map +1 -0
  148. package/lib/esm/sparql/SparqlStore.d.ts +52 -0
  149. package/lib/esm/sparql/SparqlStore.js +77 -0
  150. package/lib/esm/sparql/SparqlStore.js.map +1 -0
  151. package/lib/esm/sparql/algebraToString.d.ts +13 -0
  152. package/lib/esm/sparql/algebraToString.js +289 -0
  153. package/lib/esm/sparql/algebraToString.js.map +1 -0
  154. package/lib/esm/sparql/index.d.ts +9 -0
  155. package/lib/esm/sparql/index.js +13 -0
  156. package/lib/esm/sparql/index.js.map +1 -0
  157. package/lib/esm/sparql/irToAlgebra.d.ts +39 -0
  158. package/lib/esm/sparql/irToAlgebra.js +917 -0
  159. package/lib/esm/sparql/irToAlgebra.js.map +1 -0
  160. package/lib/esm/sparql/resultMapping.d.ts +36 -0
  161. package/lib/esm/sparql/resultMapping.js +496 -0
  162. package/lib/esm/sparql/resultMapping.js.map +1 -0
  163. package/lib/esm/sparql/sparqlUtils.d.ts +32 -0
  164. package/lib/esm/sparql/sparqlUtils.js +82 -0
  165. package/lib/esm/sparql/sparqlUtils.js.map +1 -0
  166. package/lib/esm/test-helpers/FusekiStore.d.ts +29 -0
  167. package/lib/esm/test-helpers/FusekiStore.js +78 -0
  168. package/lib/esm/test-helpers/FusekiStore.js.map +1 -0
  169. package/lib/esm/test-helpers/fuseki-test-store.d.ts +43 -0
  170. package/lib/esm/test-helpers/fuseki-test-store.js +135 -0
  171. package/lib/esm/test-helpers/fuseki-test-store.js.map +1 -0
  172. package/lib/esm/test-helpers/query-capture-store.d.ts +5 -0
  173. package/lib/esm/test-helpers/query-capture-store.js +55 -0
  174. package/lib/esm/test-helpers/query-capture-store.js.map +1 -0
  175. package/lib/esm/test-helpers/query-fixtures.d.ts +700 -117
  176. package/lib/esm/test-helpers/query-fixtures.js +38 -0
  177. package/lib/esm/test-helpers/query-fixtures.js.map +1 -1
  178. package/lib/esm/utils/LinkedStorage.d.ts +7 -7
  179. package/lib/esm/utils/LinkedStorage.js +4 -3
  180. package/lib/esm/utils/LinkedStorage.js.map +1 -1
  181. package/package.json +7 -3
  182. package/lib/cjs/interfaces/IQueryParser.d.ts +0 -13
  183. package/lib/cjs/interfaces/IQueryParser.js +0 -10
  184. package/lib/cjs/interfaces/IQueryParser.js.map +0 -1
  185. package/lib/esm/interfaces/IQueryParser.d.ts +0 -13
  186. package/lib/esm/interfaces/IQueryParser.js +0 -7
  187. package/lib/esm/interfaces/IQueryParser.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,8 +1,80 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#9](https://github.com/Semantu/linked/pull/9) [`381067b`](https://github.com/Semantu/linked/commit/381067b0fbc25f4a0446c5f8cc0eec57ddded466) Thanks [@flyon](https://github.com/flyon)! - Replaced internal query representation with a canonical backend-agnostic IR AST. `SelectQuery`, `CreateQuery`, `UpdateQuery`, and `DeleteQuery` are now typed IR objects with `kind` discriminators, compact shape/property ID references, and expression trees — replacing the previous ad-hoc nested arrays. The public Shape DSL is unchanged; what changed is what `IQuadStore` implementations receive. Store result types (`ResultRow`, `SelectResult`, `CreateResult`, `UpdateResult`) are now exported. All factories expose `build()` as the primary method. See `documentation/intermediate-representation.md` for the full IR reference and migration guidance.
8
+
9
+ - [#14](https://github.com/Semantu/linked/pull/14) [`b65e156`](https://github.com/Semantu/linked/commit/b65e15688ac173478e58e1dbb9f26dbaf5fc5a37) Thanks [@flyon](https://github.com/flyon)! - Add SPARQL conversion layer — compiles Linked IR queries into executable SPARQL and maps results back to typed DSL objects.
10
+
11
+ **New exports from `@_linked/core/sparql`:**
12
+
13
+ - **`SparqlStore`** — abstract base class for SPARQL-backed stores. Extend it and implement two methods to connect any SPARQL 1.1 endpoint:
14
+
15
+ ```ts
16
+ import { SparqlStore } from "@_linked/core/sparql";
17
+
18
+ class MyStore extends SparqlStore {
19
+ protected async executeSparqlSelect(
20
+ sparql: string
21
+ ): Promise<SparqlJsonResults> {
22
+ /* ... */
23
+ }
24
+ protected async executeSparqlUpdate(sparql: string): Promise<void> {
25
+ /* ... */
26
+ }
27
+ }
28
+ ```
29
+
30
+ - **IR → SPARQL string** convenience functions (full pipeline in one call):
31
+
32
+ - `selectToSparql(query, options?)` — SelectQuery → SPARQL string
33
+ - `createToSparql(query, options?)` — CreateQuery → SPARQL string
34
+ - `updateToSparql(query, options?)` — UpdateQuery → SPARQL string
35
+ - `deleteToSparql(query, options?)` — DeleteQuery → SPARQL string
36
+
37
+ - **IR → SPARQL algebra** (for stores that want to inspect/optimize the algebra before serialization):
38
+
39
+ - `selectToAlgebra(query, options?)` — returns `SparqlSelectPlan`
40
+ - `createToAlgebra(query, options?)` — returns `SparqlInsertDataPlan`
41
+ - `updateToAlgebra(query, options?)` — returns `SparqlDeleteInsertPlan`
42
+ - `deleteToAlgebra(query, options?)` — returns `SparqlDeleteInsertPlan`
43
+
44
+ - **Algebra → SPARQL string** serialization:
45
+
46
+ - `selectPlanToSparql(plan, options?)`, `insertDataPlanToSparql(plan, options?)`, `deleteInsertPlanToSparql(plan, options?)`, `deleteWherePlanToSparql(plan, options?)`
47
+ - `serializeAlgebraNode(node)`, `serializeExpression(expr)`, `serializeTerm(term)`
48
+
49
+ - **Result mapping** (SPARQL JSON results → typed DSL objects):
50
+
51
+ - `mapSparqlSelectResult(json, query)` — handles flat/nested/aggregated results with XSD type coercion
52
+ - `mapSparqlCreateResult(uri, query)` — echoes created fields with generated URI
53
+ - `mapSparqlUpdateResult(query)` — echoes updated fields
54
+
55
+ - **All algebra types** re-exported: `SparqlTerm`, `SparqlTriple`, `SparqlAlgebraNode`, `SparqlExpression`, `SparqlSelectPlan`, `SparqlInsertDataPlan`, `SparqlDeleteInsertPlan`, `SparqlDeleteWherePlan`, `SparqlPlan`, `SparqlOptions`, etc.
56
+
57
+ **Bug fixes included:**
58
+
59
+ - Fixed `isNodeReference()` in MutationQuery.ts — nested creates with predefined IDs (e.g., `{id: '...', name: 'Bestie'}`) now correctly insert entity data instead of only creating the link.
60
+
61
+ See [SPARQL Algebra Layer docs](./documentation/sparql-algebra.md) for the full type reference, conversion rules, and store implementation guide.
62
+
63
+ ## 1.1.0
64
+
65
+ ### Minor Changes
66
+
67
+ - [#4](https://github.com/Semantu/linked/pull/4) [`c35e686`](https://github.com/Semantu/linked/commit/c35e6861600d7aa8683b4b288fc4d1dc74c4aff2) Thanks [@flyon](https://github.com/flyon)! - - Added `Shape.selectAll()` plus nested `selectAll()` support on sub-queries.
68
+ - Added inherited property deduplication via `NodeShape.getUniquePropertyShapes()` so subclass overrides win by label and are selected once.
69
+ - Improved `selectAll()` type inference (including nested queries) and excluded base `Shape` keys from inferred results.
70
+ - Added registration-time override guards: `minCount` cannot be lowered, `maxCount` cannot be increased, and `nodeKind` cannot be widened.
71
+ - Fixed `createPropertyShape` to preserve explicit `minCount: 0` / `maxCount: 0`.
72
+ - Expanded tests and README documentation for `selectAll`, CRUD return types, and multi-value update semantics.
73
+
3
74
  ## 1.0.0
4
75
 
5
76
  ### Major Changes
77
+
6
78
  This is a rebranding + extraction release. It moves the core query/shape system into `@_linked/core` and removes RDF models and React-specific code.
7
79
 
8
80
  Key changes:
package/README.md CHANGED
@@ -1,11 +1,12 @@
1
1
  # @_linked/core
2
2
  Core Linked package for the query DSL, SHACL shape decorators/metadata, and package registration.
3
3
 
4
- Linked core gives you a type-safe, schema-parameterized query language and SHACL-driven Shape classes for linked data. It compiles queries into a plain JS query object that can be executed by a store.
4
+ Linked core gives you a type-safe, schema-parameterized query language and SHACL-driven Shape classes for linked data. It compiles queries into a normalized [Intermediate Representation (IR)](./documentation/intermediate-representation.md) that can be executed by any store.
5
5
 
6
6
  ## Linked core offers
7
7
 
8
8
  - **Schema-Parameterized Query DSL**: TypeScript-embedded queries driven by your Shape definitions.
9
+ - **Fully Inferred Result Types**: The TypeScript return type of every query is automatically inferred from the selected paths — no manual type annotations needed. Select `p.name` and get `{id: string; name: string}[]`. Select `p.friends.name` and get nested result types. This works for all operations: select, create, update, and delete.
9
10
  - **Shape Classes (SHACL)**: TypeScript classes that generate SHACL shape metadata.
10
11
  - **Object-Oriented Data Operations**: Query, create, update, and delete data using the same Shape-based API.
11
12
  - **Storage Routing**: `LinkedStorage` routes query objects to your configured store(s) that implement `IQuadStore`.
@@ -17,16 +18,151 @@ Linked core gives you a type-safe, schema-parameterized query language and SHACL
17
18
  npm install @_linked/core
18
19
  ```
19
20
 
20
- ```typescript
21
- import {Shape, LinkedStorage} from '@_linked/core';
22
- import {linkedPackage} from '@_linked/core/utils/Package';
21
+ ## Repository setup (contributors)
22
+
23
+ After cloning this repository, run:
24
+
25
+ ```bash
26
+ npm install
27
+ npm run setup
23
28
  ```
24
29
 
30
+ `npm run setup` syncs `docs/agents` into local folders for agent tooling:
31
+
32
+ - `.claude/agents`
33
+ - `.agents/agents`
34
+
25
35
  ## Related packages
26
36
 
27
37
  - `@_linked/rdf-mem-store`: in-memory RDF store that implements `IQuadStore`.
28
38
  - `@_linked/react`: React bindings for Linked queries and shapes.
29
39
 
40
+ ## Documentation
41
+
42
+ - [Intermediate Representation (IR)](./documentation/intermediate-representation.md)
43
+ - [SPARQL Algebra Layer](./documentation/sparql-algebra.md)
44
+
45
+ ## How Linked works — from shapes to query results
46
+
47
+ Linked turns TypeScript classes into a type-safe query pipeline. Here is the full flow, traced through a single example:
48
+
49
+ ```
50
+ Shape class → DSL query → IR (AST) → Target query language → Execute → Map results
51
+ ```
52
+
53
+ ### 1. SHACL shapes from TypeScript classes
54
+
55
+ Shape classes use decorators to generate SHACL metadata. These shapes define the data model, drive the DSL's type safety, and can be synced to a store for runtime data validation.
56
+
57
+ ```typescript
58
+ @linkedShape
59
+ export class Person extends Shape {
60
+ static targetClass = schema('Person');
61
+
62
+ @literalProperty({path: schema('name'), maxCount: 1})
63
+ get name(): string { return ''; }
64
+
65
+ @objectProperty({path: schema('knows'), shape: Person})
66
+ get friends(): ShapeSet<Person> { return null; }
67
+ }
68
+ ```
69
+
70
+ ### 2. Type-safe query DSL with inferred result types
71
+
72
+ The DSL uses these shape classes to provide compile-time checked queries. You cannot write a query that references a property not defined on the shape. The result type is **fully inferred** from the selected paths — no manual type annotations needed:
73
+
74
+ ```typescript
75
+ // TypeScript infers: Promise<{id: string; name: string}[]>
76
+ const result = await Person.select(p => p.name);
77
+
78
+ // TypeScript infers: Promise<{id: string; friends: {id: string; name: string}[]}[]>
79
+ const nested = await Person.select(p => p.friends.name);
80
+ ```
81
+
82
+ ### 3. SHACL-based Intermediate Representation (IR)
83
+
84
+ The DSL compiles to a backend-agnostic AST — the [Intermediate Representation](./documentation/intermediate-representation.md). This is the contract between the DSL and any store implementation.
85
+
86
+ ```json
87
+ {
88
+ "kind": "select",
89
+ "root": { "kind": "shape_scan", "shape": ".../Person", "alias": "a0" },
90
+ "projection": [
91
+ { "alias": "a1", "expression": { "kind": "property_expr", "sourceAlias": "a0", "property": ".../name" } }
92
+ ],
93
+ "resultMap": [{ "key": ".../name", "alias": "a1" }]
94
+ }
95
+ ```
96
+
97
+ The IR uses full SHACL-derived URIs for shapes and properties. Any store that implements `IQuadStore` receives these IR objects and translates them into its native query language.
98
+
99
+ ### 4. IR → SPARQL Algebra
100
+
101
+ For SPARQL-backed stores, the IR is converted into a formal [SPARQL algebra](./documentation/sparql-algebra.md) — a tree of typed nodes aligned with the SPARQL 1.1 specification.
102
+
103
+ ```
104
+ SparqlSelectPlan {
105
+ projection: [?a0, ?a0_name]
106
+ algebra: LeftJoin(
107
+ BGP(?a0 rdf:type <Person>),
108
+ BGP(?a0 <name> ?a0_name) ← wrapped in OPTIONAL
109
+ )
110
+ }
111
+ ```
112
+
113
+ Properties are wrapped in `LeftJoin` (OPTIONAL) so missing values don't eliminate result rows.
114
+
115
+ ### 5. SPARQL Algebra → SPARQL string
116
+
117
+ The algebra is a plain data structure — stores can inspect or optimize it before serialization (e.g., rewriting patterns, adding graph clauses, or pruning redundant joins).
118
+
119
+ The algebra tree is then serialized into a SPARQL query string with automatic PREFIX generation:
120
+
121
+ ```sparql
122
+ PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
123
+ SELECT DISTINCT ?a0 ?a0_name
124
+ WHERE {
125
+ ?a0 rdf:type <.../Person> .
126
+ OPTIONAL {
127
+ ?a0 <.../name> ?a0_name .
128
+ }
129
+ }
130
+ ```
131
+
132
+ ### 6. Execute and map results
133
+
134
+ The SPARQL endpoint returns JSON results, which are mapped back into typed result objects:
135
+
136
+ ```
137
+ Endpoint returns: Mapped to:
138
+ ┌──────────┬──────────┐ ┌──────────────────────────────┐
139
+ │ a0 │ a0_name │ │ { id: ".../p1", name: "Semmy" } │
140
+ │ .../p1 │ "Semmy" │ → │ { id: ".../p2", name: "Moa" } │
141
+ │ .../p2 │ "Moa" │ │ ... │
142
+ └──────────┴──────────┘ └──────────────────────────────┘
143
+ ```
144
+
145
+ Values are automatically coerced: `xsd:boolean` → `boolean`, `xsd:integer` → `number`, `xsd:dateTime` → `Date`. Nested traversals are grouped and deduplicated into nested result objects.
146
+
147
+ ### The SparqlStore base class
148
+
149
+ `SparqlStore` handles this entire pipeline. Concrete stores only implement the transport:
150
+
151
+ ```typescript
152
+ import { SparqlStore } from '@_linked/core/sparql';
153
+
154
+ class MyStore extends SparqlStore {
155
+ protected async executeSparqlSelect(sparql: string) {
156
+ // Send SPARQL to your endpoint, return JSON results
157
+ }
158
+ protected async executeSparqlUpdate(sparql: string) {
159
+ // Send SPARQL UPDATE to your endpoint
160
+ }
161
+ }
162
+ ```
163
+
164
+ See the [SPARQL Algebra Layer docs](./documentation/sparql-algebra.md) for the full type reference, conversion algorithm, and store implementation guide.
165
+
30
166
  ## Linked Package Setup
31
167
 
32
168
  Linked packages expose shapes, utilities, and ontologies through a small `package.ts` file. This makes module exports discoverable across Linked modules and enables linked decorators.
@@ -85,41 +221,35 @@ export class Person extends Shape {
85
221
  ## Queries: Create, Select, Update, Delete
86
222
 
87
223
  Queries are expressed with the same Shape classes and compile to a query object that a store executes.
224
+ Use this section as a quick start. Detailed query variations are documented in `Query examples` below.
225
+
226
+ A few quick examples:
88
227
 
228
+ **1) Select one field for all matching nodes**
89
229
  ```typescript
90
- /* Result: Array<{id: string; name: string}> */
91
230
  const names = await Person.select((p) => p.name);
231
+ /* names: {id: string; name: string}[] */
232
+ ```
92
233
 
93
- const myNode = {id: 'https://my.app/node1'};
94
- /* Result: {id: string; name: string} | null */
95
- const person = await Person.select(myNode, (p) => p.name);
96
- const missing = await Person.select({id: 'https://my.app/missing'}, (p) => p.name); // null
97
-
98
- /* Result: {id: string} & UpdatePartial<Person> */
99
- const created = await Person.create({
100
- name: 'Alice',
101
- knows: [{id: 'https://my.app/node2'}],
102
- });
234
+ **2) Select all decorated fields of nested related nodes**
235
+ ```typescript
236
+ const allFriends = await Person.select((p) => p.knows.selectAll());
237
+ /* allFriends: {
238
+ id?: string;
239
+ knows: {
240
+ id?: string;
241
+ ...all decorated Person fields...
242
+ }[]
243
+ }[] */
244
+ ```
103
245
 
246
+ **3) Apply a simple mutation**
247
+ ```typescript
248
+ const myNode = {id: 'https://my.app/node1'};
104
249
  const updated = await Person.update(myNode, {
105
250
  name: 'Alicia',
106
251
  });
107
-
108
- // Overwrite a multi-value property
109
- const overwriteFriends = await Person.update(myNode, {
110
- knows: [{id: 'https://my.app/node2'}],
111
- });
112
-
113
- // Add/remove items in a multi-value property
114
- const addRemoveFriends = await Person.update(myNode, {
115
- knows: {
116
- add: [{id: 'https://my.app/node3'}],
117
- remove: [{id: 'https://my.app/node2'}],
118
- },
119
- });
120
-
121
- /* Result: {deleted: Array<{id: string}>, count: number} */
122
- await Person.delete(myNode);
252
+ /* updated: {id: string} & UpdatePartial<Person> */
123
253
  ```
124
254
 
125
255
  ## Storage configuration
@@ -172,10 +302,13 @@ Result types are inferred from your Shape definitions and the selected paths. Ex
172
302
 
173
303
  #### Basic selection
174
304
  ```typescript
175
- /* Result: Array<{id: string; name: string}> */
305
+ /* names: {id: string; name: string}[] */
176
306
  const names = await Person.select((p) => p.name);
177
307
 
178
- /* Result: Array<{id: string; knows: Array<{id: string}>}> */
308
+ /* friends: {
309
+ id: string;
310
+ knows: { id: string }[]
311
+ }[] */
179
312
  const friends = await Person.select((p) => p.knows);
180
313
 
181
314
  const dates = await Person.select((p) => [p.birthDate, p.name]);
@@ -202,6 +335,12 @@ const deep = await Person.select((p) => p.knows.bestFriend.name);
202
335
  const detailed = await Person.select((p) =>
203
336
  p.knows.select((f) => f.name),
204
337
  );
338
+
339
+ const allPeople = await Person.selectAll();
340
+
341
+ const detailedAll = await Person.select((p) =>
342
+ p.knows.selectAll(),
343
+ );
205
344
  ```
206
345
 
207
346
  #### Where + equals
@@ -261,7 +400,9 @@ const custom = await Person.select((p) => ({
261
400
  }));
262
401
  ```
263
402
 
264
- #### Query As (type casting)
403
+ #### Query As (type casting to a sub shape)
404
+ If person.pets returns an array of Pets. And Dog extends Pet.
405
+ And you want to select properties of those pets that are dogs:
265
406
  ```typescript
266
407
  const guards = await Person.select((p) => p.pets.as(Dog).guardDogLevel);
267
408
  ```
@@ -293,34 +434,171 @@ const preloaded = await Person.select((p) => [
293
434
  ]);
294
435
  ```
295
436
 
296
- #### Create / Update / Delete
437
+ #### Create
438
+
297
439
  ```typescript
298
440
  /* Result: {id: string} & UpdatePartial<Person> */
299
441
  const created = await Person.create({name: 'Alice'});
442
+ ```
443
+ Where UpdatePartial<Shape> reflects the created properties.
444
+
445
+ #### Update
300
446
 
447
+ Update will patch any property that you send as payload and leave the rest untouched.
448
+ ```typescript
449
+ /* Result: {id: string} & UpdatePartial<Person> */
301
450
  const updated = await Person.update({id: 'https://my.app/node1'}, {name: 'Alicia'});
451
+ ```
452
+ Returns:
453
+ ```json
454
+ {
455
+ id:"https://my.app/node1",
456
+ name:"Alicia"
457
+ }
458
+ ```
459
+
460
+ **Updating multi-value properties**
461
+ When updating a property that holds multiple values (one that returns an array in the results), you can either overwrite all the values with a new explicit array of values, or delete from/add to the current values.
302
462
 
303
- // Overwrite a multi-value property
304
- const overwriteFriends = await Person.update({id: 'https://my.app/node1'}, {
305
- knows: [{id: 'https://my.app/node2'}],
463
+ To overwrite all values:
464
+ ```typescript
465
+ // Overwrite the full set of "knows" values.
466
+ const overwriteFriends = await Person.update({id: 'https://my.app/person1'}, {
467
+ knows: [{id: 'https://my.app/person2'}],
306
468
  });
469
+ ```
470
+ The result will contain an object with `updatedTo`, to indicate that previous values were overwritten to this new set of values:
471
+ ```json
472
+ {
473
+ id: "https://my.app/person1",
474
+ knows: {
475
+ updatedTo: [{id:"https://my.app/person2"}],
476
+ }
477
+ }
478
+ ```
307
479
 
308
- // Add/remove items in a multi-value property
309
- const addRemoveFriends = await Person.update({id: 'https://my.app/node1'}, {
480
+ To make incremental changes to the current set of values you can provide an object with `add` and/or `remove` keys:
481
+ ```typescript
482
+ // Add one value and remove one value without replacing the whole set.
483
+ const addRemoveFriends = await Person.update({id: 'https://my.app/person1'}, {
310
484
  knows: {
311
- add: [{id: 'https://my.app/node3'}],
312
- remove: [{id: 'https://my.app/node2'}],
485
+ add: [{id: 'https://my.app/person2'}],
486
+ remove: [{id: 'https://my.app/person3'}],
313
487
  },
314
488
  });
489
+ ```
490
+ This returns an object with the added and removed items
491
+ ```json
492
+ {
493
+ id: "https://my.app/person1",
494
+ knows: {
495
+ added?: [{id:"https://my.app/person2"},
496
+ removed?: [{id:"https://my.app/person3"}],
497
+ }
498
+ }
499
+ ```
500
+
315
501
 
316
- await Person.delete({id: 'https://my.app/node1'});
502
+ #### Delete
503
+ To delete a node entirely:
504
+
505
+ ```typescript
506
+ /* Result: {deleted: Array<{id: string}>, count: number} */
507
+ const deleted = await Person.delete({id: 'https://my.app/node1'});
508
+ ```
509
+ Returns
510
+ ```json
511
+ {
512
+ deleted:[
513
+ {id:"https://my.app/node1"}
514
+ ],
515
+ count:1
516
+ }
317
517
  ```
318
518
 
519
+ To delete multiple nodes pass an array:
520
+
521
+ ```typescript
522
+ /* Result: {deleted: Array<{id: string}>, count: number} */
523
+ const deleted = await Person.delete([{id: 'https://my.app/node1'},{id: 'https://my.app/node2'}]);
524
+ ```
525
+
526
+
527
+ ## Extending shapes
528
+
529
+ Shape classes can extend other shape classes. Subclasses inherit property shapes from their superclasses and may override them.
530
+ This example assumes `Person` from the `Shapes` section above.
531
+
532
+ ```typescript
533
+ import {literalProperty} from '@_linked/core/shapes/SHACL';
534
+ import {createNameSpace} from '@_linked/core/utils/NameSpace';
535
+ import {linkedShape} from './package';
536
+
537
+ const schema = createNameSpace('https://schema.org/');
538
+ const EmployeeClass = schema('Employee');
539
+ const name = schema('name');
540
+ const employeeId = schema('employeeId');
541
+
542
+ @linkedShape
543
+ export class Employee extends Person {
544
+ static targetClass = EmployeeClass;
545
+
546
+ // Override inherited "name" with stricter constraints (still maxCount: 1)
547
+ @literalProperty({path: name, required: true, minLength: 2, maxCount: 1})
548
+ declare name: string;
549
+
550
+ @literalProperty({path: employeeId, required: true, maxCount: 1})
551
+ declare employeeId: string;
552
+ }
553
+ ```
554
+
555
+ Override behavior:
556
+
557
+ - `NodeShape.getUniquePropertyShapes()` returns one property shape per label, with subclass overrides taking precedence.
558
+ - Overrides must be tighten-only for `minCount`, `maxCount`, and `nodeKind` (widening is rejected at registration time).
559
+ - If an override omits `minCount`, `maxCount`, or `nodeKind`, inherited values are kept.
560
+ - Current scope: compatibility checks for `datatype`, `class`, and `pattern` are not enforced yet.
561
+
319
562
  ## TODO
320
563
 
321
564
  - Allow `preloadFor` to accept another query (not just a component).
322
565
  - Make and expose functions for auto syncing shapes to the graph.
323
566
 
567
+ ## Intermediate Representation (IR)
568
+
569
+ Every Linked query compiles to a plain, JSON-serializable JavaScript object — the **Intermediate Representation**. This IR is the contract between the DSL and any storage backend. A store receives these objects and translates them into its native query language (SPARQL, SQL, etc.).
570
+
571
+ For example, this DSL call:
572
+
573
+ ```typescript
574
+ const names = await Person.select((p) => p.name);
575
+ ```
576
+
577
+ produces the following IR object, which is passed to your store's `selectQuery()` method:
578
+
579
+ ```json
580
+ {
581
+ "kind": "select",
582
+ "root": {"kind": "shape_scan", "shape": "https://schema.org/Person", "alias": "a0"},
583
+ "patterns": [],
584
+ "projection": [
585
+ {
586
+ "alias": "a1",
587
+ "expression": {"kind": "property_expr", "sourceAlias": "a0", "property": "https://schema.org/name"}
588
+ }
589
+ ],
590
+ "resultMap": [{"key": "name", "alias": "a1"}],
591
+ "singleResult": false
592
+ }
593
+ ```
594
+
595
+ All IR types are available from `@_linked/core/queries/IntermediateRepresentation`. See the full [Intermediate Representation docs](./documentation/intermediate-representation.md) for the complete type reference, examples, and a store implementer guide.
596
+
597
+ **Store packages:**
598
+
599
+ - `SparqlStore` base class — included in `@_linked/core/sparql`, extend it for any SPARQL endpoint
600
+ - `@_linked/rdf-mem-store` — in-memory RDF store
601
+
324
602
  ## Changelog
325
603
 
326
604
  See [CHANGELOG.md](./CHANGELOG.md).
package/lib/cjs/index.js CHANGED
@@ -61,6 +61,7 @@ const DeleteQuery = __importStar(require("./queries/DeleteQuery.js"));
61
61
  const CreateQuery = __importStar(require("./queries/CreateQuery.js"));
62
62
  const QueryParser = __importStar(require("./queries/QueryParser.js"));
63
63
  const QueryFactory = __importStar(require("./queries/QueryFactory.js"));
64
+ const IntermediateRepresentation = __importStar(require("./queries/IntermediateRepresentation.js"));
64
65
  const NameSpace = __importStar(require("./utils/NameSpace.js"));
65
66
  const ShapeClass = __importStar(require("./utils/ShapeClass.js"));
66
67
  const cached = __importStar(require("./utils/cached.js"));
@@ -75,6 +76,7 @@ const shacl = __importStar(require("./ontologies/shacl.js"));
75
76
  const lincd = __importStar(require("./ontologies/lincd.js"));
76
77
  const owl = __importStar(require("./ontologies/owl.js"));
77
78
  const npm = __importStar(require("./ontologies/npm.js"));
79
+ const Sparql = __importStar(require("./sparql/index.js"));
78
80
  const next_tick_1 = __importDefault(require("next-tick"));
79
81
  exports.nextTick = next_tick_1.default;
80
82
  function initModularApp() {
@@ -103,6 +105,7 @@ function initModularApp() {
103
105
  CreateQuery,
104
106
  QueryParser,
105
107
  QueryFactory,
108
+ IntermediateRepresentation,
106
109
  SHACLShapes,
107
110
  rdf,
108
111
  rdfs,
@@ -111,6 +114,7 @@ function initModularApp() {
111
114
  lincd,
112
115
  owl,
113
116
  npm,
117
+ Sparql,
114
118
  };
115
119
  var lincdExport = {};
116
120
  for (let fileKey in publicFiles) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,wCA+CC;AAvFD;;;;GAIG;AACH,4DAA8C;AAC9C,kFAAoE;AACpE,gFAAkE;AAClE,wEAA0D;AAC1D,kEAAoD;AACpD,kEAAoD;AACpD,yDAA2C;AAC3C,+DAAiD;AACjD,oEAAsD;AACtD,0DAA4C;AAC5C,oDAAsC;AACtC,sEAAwD;AACxD,sEAAwD;AACxD,0EAA4D;AAC5D,sEAAwD;AACxD,sEAAwD;AACxD,sEAAwD;AACxD,wEAA0D;AAC1D,gEAAkD;AAClD,kEAAoD;AACpD,0DAA4C;AAC5C,uDAAyC;AACzC,6EAA+D;AAC/D,uEAAyD;AACzD,uEAAyD;AACzD,yDAA2C;AAC3C,2DAA6C;AAC7C,yDAA2C;AAC3C,6DAA+C;AAC/C,6DAA+C;AAC/C,yDAA2C;AAC3C,yDAA2C;AAC3C,0DAAiC;AACzB,mBADD,mBAAQ,CACC;AAEhB,SAAgB,cAAc;IAC5B,IAAI,WAAW,GAAG;QAChB,OAAO;QACP,kBAAkB;QAClB,iBAAiB;QACjB,aAAa;QACb,OAAO;QACP,OAAO;QACP,KAAK;QACL,QAAQ;QACR,MAAM;QACN,SAAS;QACT,MAAM;QACN,GAAG;QACH,UAAU;QACV,IAAI;QACJ,aAAa;QACb,UAAU;QACV,UAAU;QACV,WAAW;QACX,WAAW;QACX,aAAa;QACb,WAAW;QACX,WAAW;QACX,WAAW;QACX,YAAY;QACZ,WAAW;QACX,GAAG;QACH,IAAI;QACJ,GAAG;QACH,KAAK;QACL,KAAK;QACL,GAAG;QACH,GAAG;KACJ,CAAC;IACF,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,KAAK,IAAI,OAAO,IAAI,WAAW,EAAE,CAAC;QAChC,IAAI,eAAe,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QAC3C,KAAK,IAAI,SAAS,IAAI,eAAe,EAAE,CAAC;YACtC,WAAW,CAAC,SAAS,CAAC,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC;IAC9C,CAAC;SAAM,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0CA,wCAiDC;AA3FD;;;;GAIG;AACH,4DAA8C;AAC9C,kFAAoE;AACpE,gFAAkE;AAClE,wEAA0D;AAC1D,kEAAoD;AACpD,kEAAoD;AACpD,yDAA2C;AAC3C,+DAAiD;AACjD,oEAAsD;AACtD,0DAA4C;AAC5C,oDAAsC;AACtC,sEAAwD;AACxD,sEAAwD;AACxD,0EAA4D;AAC5D,sEAAwD;AACxD,sEAAwD;AACxD,sEAAwD;AACxD,wEAA0D;AAC1D,oGAAsF;AACtF,gEAAkD;AAClD,kEAAoD;AACpD,0DAA4C;AAC5C,uDAAyC;AACzC,6EAA+D;AAC/D,uEAAyD;AACzD,uEAAyD;AACzD,yDAA2C;AAC3C,2DAA6C;AAC7C,yDAA2C;AAC3C,6DAA+C;AAC/C,6DAA+C;AAC/C,yDAA2C;AAC3C,yDAA2C;AAC3C,0DAA4C;AAC5C,0DAAiC;AACzB,mBADD,mBAAQ,CACC;AAEhB,SAAgB,cAAc;IAC5B,IAAI,WAAW,GAAG;QAChB,OAAO;QACP,kBAAkB;QAClB,iBAAiB;QACjB,aAAa;QACb,OAAO;QACP,OAAO;QACP,KAAK;QACL,QAAQ;QACR,MAAM;QACN,SAAS;QACT,MAAM;QACN,GAAG;QACH,UAAU;QACV,IAAI;QACJ,aAAa;QACb,UAAU;QACV,UAAU;QACV,WAAW;QACX,WAAW;QACX,aAAa;QACb,WAAW;QACX,WAAW;QACX,WAAW;QACX,YAAY;QACZ,0BAA0B;QAC1B,WAAW;QACX,GAAG;QACH,IAAI;QACJ,GAAG;QACH,KAAK;QACL,KAAK;QACL,GAAG;QACH,GAAG;QACH,MAAM;KACP,CAAC;IACF,IAAI,WAAW,GAAG,EAAE,CAAC;IACrB,KAAK,IAAI,OAAO,IAAI,WAAW,EAAE,CAAC;QAChC,IAAI,eAAe,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;QAC3C,KAAK,IAAI,SAAS,IAAI,eAAe,EAAE,CAAC;YACtC,WAAW,CAAC,SAAS,CAAC,GAAG,eAAe,CAAC,SAAS,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAClC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC;IAC9C,CAAC;SAAM,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC"}
@@ -1,14 +1,26 @@
1
- import { CreateQuery } from '../queries/CreateQuery.js';
2
- import { DeleteQuery, DeleteResponse } from '../queries/DeleteQuery.js';
3
- import { SelectQuery } from '../queries/SelectQuery.js';
4
- import { UpdateQuery } from '../queries/UpdateQuery.js';
1
+ import type { SelectQuery } from '../queries/SelectQuery.js';
2
+ import type { CreateQuery } from '../queries/CreateQuery.js';
3
+ import type { UpdateQuery } from '../queries/UpdateQuery.js';
4
+ import type { DeleteQuery, DeleteResponse } from '../queries/DeleteQuery.js';
5
+ import type { SelectResult, CreateResult, UpdateResult } from '../queries/IntermediateRepresentation.js';
6
+ /**
7
+ * Store interface for executing IR queries.
8
+ *
9
+ * Implement this interface to back Linked with a custom storage engine
10
+ * (SPARQL endpoint, SQL database, in-memory store, etc.).
11
+ *
12
+ * Each method receives a canonical IR query object and returns the result.
13
+ * The calling layer (LinkedStorage / QueryParser) threads the precise
14
+ * DSL-level TypeScript result type back to the caller — the store only
15
+ * needs to produce data that matches the structural result types.
16
+ */
5
17
  export interface IQuadStore {
6
18
  /**
7
19
  * Prepares the store to be used.
8
20
  */
9
21
  init?(): Promise<any>;
10
- selectQuery<ResultType>(query: SelectQuery<any>): Promise<ResultType>;
11
- updateQuery?<RType>(q: UpdateQuery<RType>): Promise<RType>;
12
- createQuery?<R>(q: CreateQuery<R>): Promise<R>;
22
+ selectQuery(query: SelectQuery): Promise<SelectResult>;
23
+ updateQuery?(query: UpdateQuery): Promise<UpdateResult>;
24
+ createQuery?(query: CreateQuery): Promise<CreateResult>;
13
25
  deleteQuery?(query: DeleteQuery): Promise<DeleteResponse>;
14
26
  }
@@ -1,18 +1,17 @@
1
1
  import { Shape } from '../shapes/Shape.js';
2
- import { NodeShape } from '../shapes/SHACL.js';
3
- import { LinkedQuery } from './SelectQuery.js';
4
2
  import { AddId, NodeDescriptionValue, UpdatePartial } from './QueryFactory.js';
5
3
  import { MutationQueryFactory } from './MutationQuery.js';
6
- export interface CreateQuery<ResponseType = null> extends LinkedQuery {
7
- type: 'create';
8
- shape: NodeShape;
9
- description: NodeDescriptionValue;
10
- }
4
+ import { IRCreateMutation } from './IntermediateRepresentation.js';
5
+ /**
6
+ * The canonical CreateQuery type — an IR AST node representing a create mutation.
7
+ * This is the type received by IQuadStore.createQuery().
8
+ */
9
+ export type CreateQuery = IRCreateMutation;
11
10
  export type CreateResponse<U> = AddId<U, true>;
12
11
  export declare class CreateQueryFactory<ShapeType extends Shape, U extends UpdatePartial<ShapeType>> extends MutationQueryFactory {
13
12
  shapeClass: typeof Shape;
14
13
  readonly id: string;
15
14
  readonly description: NodeDescriptionValue;
16
15
  constructor(shapeClass: typeof Shape, updateObjectOrFn: U);
17
- getQueryObject(): CreateQuery<AddId<U, true>>;
16
+ build(): CreateQuery;
18
17
  }
@@ -2,18 +2,18 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CreateQueryFactory = void 0;
4
4
  const MutationQuery_js_1 = require("./MutationQuery.js");
5
+ const IRMutation_js_1 = require("./IRMutation.js");
5
6
  class CreateQueryFactory extends MutationQuery_js_1.MutationQueryFactory {
6
7
  constructor(shapeClass, updateObjectOrFn) {
7
8
  super();
8
9
  this.shapeClass = shapeClass;
9
10
  this.description = this.convertUpdateObject(updateObjectOrFn, this.shapeClass.shape, true);
10
11
  }
11
- getQueryObject() {
12
- return {
13
- type: 'create',
12
+ build() {
13
+ return (0, IRMutation_js_1.buildCanonicalCreateMutationIR)({
14
14
  shape: this.shapeClass.shape,
15
15
  description: this.description,
16
- };
16
+ });
17
17
  }
18
18
  }
19
19
  exports.CreateQueryFactory = CreateQueryFactory;
@@ -1 +1 @@
1
- {"version":3,"file":"CreateQuery.js","sourceRoot":"","sources":["../../../src/queries/CreateQuery.ts"],"names":[],"mappings":";;;AAIA,yDAAwD;AAUxD,MAAa,kBAGX,SAAQ,uCAAoB;IAI5B,YACS,UAAwB,EAC/B,gBAAmB;QAEnB,KAAK,EAAE,CAAC;QAHD,eAAU,GAAV,UAAU,CAAc;QAI/B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,mBAAmB,CACzC,gBAAgB,EAChB,IAAI,CAAC,UAAU,CAAC,KAAK,EACrB,IAAI,CACL,CAAC;IACJ,CAAC;IAED,cAAc;QACZ,OAAO;YACL,IAAI,EAAE,QAAQ;YACd,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK;YAC5B,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,CAAC;IACJ,CAAC;CACF;AA1BD,gDA0BC"}
1
+ {"version":3,"file":"CreateQuery.js","sourceRoot":"","sources":["../../../src/queries/CreateQuery.ts"],"names":[],"mappings":";;;AAEA,yDAAwD;AAExD,mDAA+D;AAU/D,MAAa,kBAGX,SAAQ,uCAAoB;IAI5B,YACS,UAAwB,EAC/B,gBAAmB;QAEnB,KAAK,EAAE,CAAC;QAHD,eAAU,GAAV,UAAU,CAAc;QAI/B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,mBAAmB,CACzC,gBAAgB,EAChB,IAAI,CAAC,UAAU,CAAC,KAAK,EACrB,IAAI,CACL,CAAC;IACJ,CAAC;IAED,KAAK;QACH,OAAO,IAAA,8CAA8B,EAAC;YACpC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK;YAC5B,WAAW,EAAE,IAAI,CAAC,WAAW;SAC9B,CAAC,CAAC;IACL,CAAC;CACF;AAzBD,gDAyBC"}