@_linked/core 1.2.0-next.20260304061428 → 1.2.0-next.20260312041833

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 (185) hide show
  1. package/CHANGELOG.md +32 -53
  2. package/README.md +401 -54
  3. package/lib/cjs/expressions/Expr.d.ts +58 -0
  4. package/lib/cjs/expressions/Expr.js +217 -0
  5. package/lib/cjs/expressions/Expr.js.map +1 -0
  6. package/lib/cjs/expressions/ExpressionMethods.d.ts +81 -0
  7. package/lib/cjs/expressions/ExpressionMethods.js +3 -0
  8. package/lib/cjs/expressions/ExpressionMethods.js.map +1 -0
  9. package/lib/cjs/expressions/ExpressionNode.d.ts +95 -0
  10. package/lib/cjs/expressions/ExpressionNode.js +349 -0
  11. package/lib/cjs/expressions/ExpressionNode.js.map +1 -0
  12. package/lib/cjs/index.d.ts +14 -2
  13. package/lib/cjs/index.js +36 -6
  14. package/lib/cjs/index.js.map +1 -1
  15. package/lib/cjs/package.d.ts +1 -1
  16. package/lib/cjs/queries/CreateBuilder.d.ts +38 -0
  17. package/lib/cjs/queries/CreateBuilder.js +100 -0
  18. package/lib/cjs/queries/CreateBuilder.js.map +1 -0
  19. package/lib/cjs/queries/CreateQuery.d.ts +3 -3
  20. package/lib/cjs/queries/CreateQuery.js.map +1 -1
  21. package/lib/cjs/queries/DeleteBuilder.d.ts +36 -0
  22. package/lib/cjs/queries/DeleteBuilder.js +112 -0
  23. package/lib/cjs/queries/DeleteBuilder.js.map +1 -0
  24. package/lib/cjs/queries/DeleteQuery.d.ts +5 -5
  25. package/lib/cjs/queries/DeleteQuery.js.map +1 -1
  26. package/lib/cjs/queries/FieldSet.d.ts +206 -0
  27. package/lib/cjs/queries/FieldSet.js +549 -0
  28. package/lib/cjs/queries/FieldSet.js.map +1 -0
  29. package/lib/cjs/queries/IRCanonicalize.d.ts +10 -3
  30. package/lib/cjs/queries/IRCanonicalize.js +10 -1
  31. package/lib/cjs/queries/IRCanonicalize.js.map +1 -1
  32. package/lib/cjs/queries/IRDesugar.d.ts +43 -10
  33. package/lib/cjs/queries/IRDesugar.js +165 -134
  34. package/lib/cjs/queries/IRDesugar.js.map +1 -1
  35. package/lib/cjs/queries/IRLower.d.ts +19 -2
  36. package/lib/cjs/queries/IRLower.js +105 -20
  37. package/lib/cjs/queries/IRLower.js.map +1 -1
  38. package/lib/cjs/queries/IRMutation.d.ts +31 -1
  39. package/lib/cjs/queries/IRMutation.js +68 -15
  40. package/lib/cjs/queries/IRMutation.js.map +1 -1
  41. package/lib/cjs/queries/IntermediateRepresentation.d.ts +34 -4
  42. package/lib/cjs/queries/MutationQuery.d.ts +1 -1
  43. package/lib/cjs/queries/MutationQuery.js +17 -8
  44. package/lib/cjs/queries/MutationQuery.js.map +1 -1
  45. package/lib/cjs/queries/PropertyPath.d.ts +38 -0
  46. package/lib/cjs/queries/PropertyPath.js +82 -0
  47. package/lib/cjs/queries/PropertyPath.js.map +1 -0
  48. package/lib/cjs/queries/ProxiedPathBuilder.d.ts +14 -0
  49. package/lib/cjs/queries/ProxiedPathBuilder.js +29 -0
  50. package/lib/cjs/queries/ProxiedPathBuilder.js.map +1 -0
  51. package/lib/cjs/queries/QueryBuilder.d.ts +154 -0
  52. package/lib/cjs/queries/QueryBuilder.js +391 -0
  53. package/lib/cjs/queries/QueryBuilder.js.map +1 -0
  54. package/lib/cjs/queries/QueryFactory.d.ts +2 -1
  55. package/lib/cjs/queries/QueryFactory.js.map +1 -1
  56. package/lib/cjs/queries/SelectQuery.d.ts +66 -136
  57. package/lib/cjs/queries/SelectQuery.js +111 -526
  58. package/lib/cjs/queries/SelectQuery.js.map +1 -1
  59. package/lib/cjs/queries/UpdateBuilder.d.ts +46 -0
  60. package/lib/cjs/queries/UpdateBuilder.js +133 -0
  61. package/lib/cjs/queries/UpdateBuilder.js.map +1 -0
  62. package/lib/cjs/queries/UpdateQuery.d.ts +5 -5
  63. package/lib/cjs/queries/UpdateQuery.js.map +1 -1
  64. package/lib/cjs/queries/WhereCondition.d.ts +18 -0
  65. package/lib/cjs/queries/WhereCondition.js +3 -0
  66. package/lib/cjs/queries/WhereCondition.js.map +1 -0
  67. package/lib/cjs/queries/resolveShape.d.ts +10 -0
  68. package/lib/cjs/queries/resolveShape.js +23 -0
  69. package/lib/cjs/queries/resolveShape.js.map +1 -0
  70. package/lib/cjs/shapes/SHACL.js +7 -5
  71. package/lib/cjs/shapes/SHACL.js.map +1 -1
  72. package/lib/cjs/shapes/Shape.d.ts +39 -52
  73. package/lib/cjs/shapes/Shape.js +32 -56
  74. package/lib/cjs/shapes/Shape.js.map +1 -1
  75. package/lib/cjs/sparql/SparqlAlgebra.d.ts +6 -1
  76. package/lib/cjs/sparql/SparqlStore.js +15 -0
  77. package/lib/cjs/sparql/SparqlStore.js.map +1 -1
  78. package/lib/cjs/sparql/algebraToString.js +10 -0
  79. package/lib/cjs/sparql/algebraToString.js.map +1 -1
  80. package/lib/cjs/sparql/irToAlgebra.d.ts +34 -3
  81. package/lib/cjs/sparql/irToAlgebra.js +386 -33
  82. package/lib/cjs/sparql/irToAlgebra.js.map +1 -1
  83. package/lib/cjs/test-helpers/query-fixtures.d.ts +453 -3046
  84. package/lib/cjs/test-helpers/query-fixtures.js +143 -25
  85. package/lib/cjs/test-helpers/query-fixtures.js.map +1 -1
  86. package/lib/cjs/test-helpers/test-utils.d.ts +18 -0
  87. package/lib/cjs/test-helpers/test-utils.js +47 -0
  88. package/lib/cjs/test-helpers/test-utils.js.map +1 -0
  89. package/lib/cjs/utils/Package.d.ts +8 -8
  90. package/lib/cjs/utils/Package.js.map +1 -1
  91. package/lib/cjs/utils/ShapeClass.d.ts +2 -2
  92. package/lib/cjs/utils/ShapeClass.js +4 -22
  93. package/lib/cjs/utils/ShapeClass.js.map +1 -1
  94. package/lib/esm/expressions/Expr.d.ts +58 -0
  95. package/lib/esm/expressions/Expr.js +214 -0
  96. package/lib/esm/expressions/Expr.js.map +1 -0
  97. package/lib/esm/expressions/ExpressionMethods.d.ts +81 -0
  98. package/lib/esm/expressions/ExpressionMethods.js +2 -0
  99. package/lib/esm/expressions/ExpressionMethods.js.map +1 -0
  100. package/lib/esm/expressions/ExpressionNode.d.ts +95 -0
  101. package/lib/esm/expressions/ExpressionNode.js +341 -0
  102. package/lib/esm/expressions/ExpressionNode.js.map +1 -0
  103. package/lib/esm/index.d.ts +14 -2
  104. package/lib/esm/index.js +26 -2
  105. package/lib/esm/index.js.map +1 -1
  106. package/lib/esm/package.d.ts +1 -1
  107. package/lib/esm/queries/CreateBuilder.d.ts +38 -0
  108. package/lib/esm/queries/CreateBuilder.js +96 -0
  109. package/lib/esm/queries/CreateBuilder.js.map +1 -0
  110. package/lib/esm/queries/CreateQuery.d.ts +3 -3
  111. package/lib/esm/queries/CreateQuery.js.map +1 -1
  112. package/lib/esm/queries/DeleteBuilder.d.ts +36 -0
  113. package/lib/esm/queries/DeleteBuilder.js +108 -0
  114. package/lib/esm/queries/DeleteBuilder.js.map +1 -0
  115. package/lib/esm/queries/DeleteQuery.d.ts +5 -5
  116. package/lib/esm/queries/DeleteQuery.js.map +1 -1
  117. package/lib/esm/queries/FieldSet.d.ts +206 -0
  118. package/lib/esm/queries/FieldSet.js +545 -0
  119. package/lib/esm/queries/FieldSet.js.map +1 -0
  120. package/lib/esm/queries/IRCanonicalize.d.ts +10 -3
  121. package/lib/esm/queries/IRCanonicalize.js +10 -1
  122. package/lib/esm/queries/IRCanonicalize.js.map +1 -1
  123. package/lib/esm/queries/IRDesugar.d.ts +43 -10
  124. package/lib/esm/queries/IRDesugar.js +160 -130
  125. package/lib/esm/queries/IRDesugar.js.map +1 -1
  126. package/lib/esm/queries/IRLower.d.ts +19 -2
  127. package/lib/esm/queries/IRLower.js +102 -19
  128. package/lib/esm/queries/IRLower.js.map +1 -1
  129. package/lib/esm/queries/IRMutation.d.ts +31 -1
  130. package/lib/esm/queries/IRMutation.js +63 -14
  131. package/lib/esm/queries/IRMutation.js.map +1 -1
  132. package/lib/esm/queries/IntermediateRepresentation.d.ts +34 -4
  133. package/lib/esm/queries/MutationQuery.d.ts +1 -1
  134. package/lib/esm/queries/MutationQuery.js +17 -8
  135. package/lib/esm/queries/MutationQuery.js.map +1 -1
  136. package/lib/esm/queries/PropertyPath.d.ts +38 -0
  137. package/lib/esm/queries/PropertyPath.js +77 -0
  138. package/lib/esm/queries/PropertyPath.js.map +1 -0
  139. package/lib/esm/queries/ProxiedPathBuilder.d.ts +14 -0
  140. package/lib/esm/queries/ProxiedPathBuilder.js +26 -0
  141. package/lib/esm/queries/ProxiedPathBuilder.js.map +1 -0
  142. package/lib/esm/queries/QueryBuilder.d.ts +154 -0
  143. package/lib/esm/queries/QueryBuilder.js +387 -0
  144. package/lib/esm/queries/QueryBuilder.js.map +1 -0
  145. package/lib/esm/queries/QueryFactory.d.ts +2 -1
  146. package/lib/esm/queries/QueryFactory.js.map +1 -1
  147. package/lib/esm/queries/SelectQuery.d.ts +66 -136
  148. package/lib/esm/queries/SelectQuery.js +105 -515
  149. package/lib/esm/queries/SelectQuery.js.map +1 -1
  150. package/lib/esm/queries/UpdateBuilder.d.ts +46 -0
  151. package/lib/esm/queries/UpdateBuilder.js +129 -0
  152. package/lib/esm/queries/UpdateBuilder.js.map +1 -0
  153. package/lib/esm/queries/UpdateQuery.d.ts +5 -5
  154. package/lib/esm/queries/UpdateQuery.js.map +1 -1
  155. package/lib/esm/queries/WhereCondition.d.ts +18 -0
  156. package/lib/esm/queries/WhereCondition.js +2 -0
  157. package/lib/esm/queries/WhereCondition.js.map +1 -0
  158. package/lib/esm/queries/resolveShape.d.ts +10 -0
  159. package/lib/esm/queries/resolveShape.js +20 -0
  160. package/lib/esm/queries/resolveShape.js.map +1 -0
  161. package/lib/esm/shapes/SHACL.js +7 -5
  162. package/lib/esm/shapes/SHACL.js.map +1 -1
  163. package/lib/esm/shapes/Shape.d.ts +39 -52
  164. package/lib/esm/shapes/Shape.js +32 -53
  165. package/lib/esm/shapes/Shape.js.map +1 -1
  166. package/lib/esm/sparql/SparqlAlgebra.d.ts +6 -1
  167. package/lib/esm/sparql/SparqlStore.js +16 -1
  168. package/lib/esm/sparql/SparqlStore.js.map +1 -1
  169. package/lib/esm/sparql/algebraToString.js +10 -0
  170. package/lib/esm/sparql/algebraToString.js.map +1 -1
  171. package/lib/esm/sparql/irToAlgebra.d.ts +34 -3
  172. package/lib/esm/sparql/irToAlgebra.js +380 -33
  173. package/lib/esm/sparql/irToAlgebra.js.map +1 -1
  174. package/lib/esm/test-helpers/query-fixtures.d.ts +453 -3046
  175. package/lib/esm/test-helpers/query-fixtures.js +143 -25
  176. package/lib/esm/test-helpers/query-fixtures.js.map +1 -1
  177. package/lib/esm/test-helpers/test-utils.d.ts +18 -0
  178. package/lib/esm/test-helpers/test-utils.js +41 -0
  179. package/lib/esm/test-helpers/test-utils.js.map +1 -0
  180. package/lib/esm/utils/Package.d.ts +8 -8
  181. package/lib/esm/utils/Package.js.map +1 -1
  182. package/lib/esm/utils/ShapeClass.d.ts +2 -2
  183. package/lib/esm/utils/ShapeClass.js +4 -22
  184. package/lib/esm/utils/ShapeClass.js.map +1 -1
  185. package/package.json +3 -3
package/CHANGELOG.md CHANGED
@@ -4,73 +4,52 @@
4
4
 
5
5
  ### Minor Changes
6
6
 
7
- - [#20](https://github.com/Semantu/linked/pull/20) [`33e9fb0`](https://github.com/Semantu/linked/commit/33e9fb0205343eca8c84723cbabc3f3342e40be5) Thanks [@flyon](https://github.com/flyon)! - **Breaking:** `QueryParser` has been removed. If you imported `QueryParser` directly, replace with `getQueryDispatch()` from `@_linked/core/queries/queryDispatch`. The Shape DSL (`Shape.select()`, `.create()`, `.update()`, `.delete()`) and `SelectQuery.exec()` are unchanged.
7
+ - [#31](https://github.com/Semantu/linked/pull/31) [`eb88865`](https://github.com/Semantu/linked/commit/eb8886564f2c9663805c4308a834ca615f9a1dab) Thanks [@flyon](https://github.com/flyon)! - Properties in `select()` and `update()` now support expressions you can compute values dynamically instead of just reading or writing raw fields.
8
8
 
9
- **New:** `getQueryDispatch()` and `setQueryDispatch()` are now exported, allowing custom query dispatch implementations (e.g. for testing or alternative storage backends) without subclassing `LinkedStorage`.
9
+ ### What's new
10
10
 
11
- - [#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.
11
+ - **Computed fields in queries** chain expression methods on properties to derive new values: string manipulation (`.strlen()`, `.ucase()`, `.concat()`), arithmetic (`.plus()`, `.times()`, `.abs()`), date extraction (`.year()`, `.month()`, `.hours()`), and comparisons (`.gt()`, `.eq()`, `.contains()`).
12
12
 
13
- - [#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.
14
-
15
- **New exports from `@_linked/core/sparql`:**
16
-
17
- - **`SparqlStore`** — abstract base class for SPARQL-backed stores. Extend it and implement two methods to connect any SPARQL 1.1 endpoint:
18
-
19
- ```ts
20
- import { SparqlStore } from "@_linked/core/sparql";
21
-
22
- class MyStore extends SparqlStore {
23
- protected async executeSparqlSelect(
24
- sparql: string
25
- ): Promise<SparqlJsonResults> {
26
- /* ... */
27
- }
28
- protected async executeSparqlUpdate(sparql: string): Promise<void> {
29
- /* ... */
30
- }
31
- }
13
+ ```typescript
14
+ await Person.select((p) => ({
15
+ name: p.name,
16
+ nameLen: p.name.strlen(),
17
+ ageInMonths: p.age.times(12),
18
+ }));
32
19
  ```
33
20
 
34
- - **IR SPARQL string** convenience functions (full pipeline in one call):
35
-
36
- - `selectToSparql(query, options?)` — SelectQuery → SPARQL string
37
- - `createToSparql(query, options?)` — CreateQuery → SPARQL string
38
- - `updateToSparql(query, options?)` — UpdateQuery → SPARQL string
39
- - `deleteToSparql(query, options?)` — DeleteQuery → SPARQL string
40
-
41
- - **IR → SPARQL algebra** (for stores that want to inspect/optimize the algebra before serialization):
42
-
43
- - `selectToAlgebra(query, options?)` — returns `SparqlSelectPlan`
44
- - `createToAlgebra(query, options?)` — returns `SparqlInsertDataPlan`
45
- - `updateToAlgebra(query, options?)` — returns `SparqlDeleteInsertPlan`
46
- - `deleteToAlgebra(query, options?)` — returns `SparqlDeleteInsertPlan`
47
-
48
- - **Algebra → SPARQL string** serialization:
21
+ - **Expression-based WHERE filters** filter using computed conditions, not just equality checks. Works on queries, updates, and deletes.
49
22
 
50
- - `selectPlanToSparql(plan, options?)`, `insertDataPlanToSparql(plan, options?)`, `deleteInsertPlanToSparql(plan, options?)`, `deleteWherePlanToSparql(plan, options?)`
51
- - `serializeAlgebraNode(node)`, `serializeExpression(expr)`, `serializeTerm(term)`
52
-
53
- - **Result mapping** (SPARQL JSON results → typed DSL objects):
54
-
55
- - `mapSparqlSelectResult(json, query)` — handles flat/nested/aggregated results with XSD type coercion
56
- - `mapSparqlCreateResult(uri, query)` — echoes created fields with generated URI
57
- - `mapSparqlUpdateResult(query)` — echoes updated fields
23
+ ```typescript
24
+ await Person.select((p) => p.name).where((p) => p.name.strlen().gt(5));
25
+ await Person.update({ verified: true }).where((p) => p.age.gte(18));
26
+ ```
58
27
 
59
- - **All algebra types** re-exported: `SparqlTerm`, `SparqlTriple`, `SparqlAlgebraNode`, `SparqlExpression`, `SparqlSelectPlan`, `SparqlInsertDataPlan`, `SparqlDeleteInsertPlan`, `SparqlDeleteWherePlan`, `SparqlPlan`, `SparqlOptions`, etc.
28
+ - **Computed updates** when updating data, calculate new values based on existing ones instead of providing static values. Pass a callback to `update()` to reference current field values.
60
29
 
61
- **Bug fixes included:**
30
+ ```typescript
31
+ await Person.update((p) => ({ age: p.age.plus(1) })).for(entity);
32
+ await Person.update((p) => ({
33
+ label: p.firstName.concat(" ").concat(p.lastName),
34
+ })).for(entity);
35
+ ```
62
36
 
63
- - 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.
37
+ - **`Expr` module**for expressions that don't start from a property, like the current timestamp, conditional logic, or coalescing nulls.
64
38
 
65
- See [SPARQL Algebra Layer docs](./documentation/sparql-algebra.md) for the full type reference, conversion rules, and store implementation guide.
39
+ ```typescript
40
+ await Person.update({ lastSeen: Expr.now() }).for(entity);
41
+ await Person.select((p) => ({
42
+ displayName: Expr.firstDefined(p.nickname, p.name),
43
+ }));
44
+ ```
66
45
 
67
- ### Patch Changes
46
+ Update expression callbacks are fully typed — `.plus()` only appears on number properties, `.strlen()` only on strings, etc.
68
47
 
69
- - [#17](https://github.com/Semantu/linked/pull/17) [`0654780`](https://github.com/Semantu/linked/commit/06547807a7bae56e992eba73263f83e092b7788b) Thanks [@flyon](https://github.com/flyon)! - Preserve nested array sub-select branches in canonical IR so `build()` emits complete traversals, projection fields, and `resultMap` entries for nested selections.
48
+ ### New exports
70
49
 
71
- This fixes cases where nested branches present in `toRawInput().select` were dropped during desugar/lowering (for example nested `friends.select([name, hobby])` branches under another sub-select).
50
+ `ExpressionNode`, `Expr`, `ExpressionInput`, `PropertyRefMap`, `ExpressionUpdateProxy<S>`, `ExpressionUpdateResult<S>`, and per-type method interfaces (`NumericExpressionMethods`, `StringExpressionMethods`, `DateExpressionMethods`, `BooleanExpressionMethods`, `BaseExpressionMethods`).
72
51
 
73
- Also adds regression coverage for desugar preservation, IR lowering completeness, and updated SPARQL golden output for nested query fixtures.
52
+ See the [README](./README.md#computed-expressions) for the full method reference and more examples.
74
53
 
75
54
  ## 1.1.0
76
55