@lix-js/sdk 0.6.0-preview.4 → 0.6.0-preview.5

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 (234) hide show
  1. package/README.md +1 -1
  2. package/SKILL.md +65 -64
  3. package/dist/engine-wasm/index.js +4 -4
  4. package/dist/engine-wasm/wasm/lix_engine.d.ts +5 -5
  5. package/dist/engine-wasm/wasm/lix_engine.js +130 -118
  6. package/dist/engine-wasm/wasm/lix_engine.wasm +0 -0
  7. package/dist/engine-wasm/wasm/lix_engine.wasm.d.ts +9 -8
  8. package/dist/generated/builtin-schemas.d.ts +69 -69
  9. package/dist/generated/builtin-schemas.js +94 -94
  10. package/dist/open-lix.d.ts +33 -26
  11. package/dist/open-lix.js +10 -10
  12. package/dist/sqlite/index.js +86 -30
  13. package/dist-engine-src/README.md +3 -3
  14. package/dist-engine-src/src/backend/capabilities.rs +67 -0
  15. package/dist-engine-src/src/backend/conformance/baseline.rs +1127 -0
  16. package/dist-engine-src/src/backend/conformance/factory.rs +93 -0
  17. package/dist-engine-src/src/backend/conformance/failure_tests.rs +608 -0
  18. package/dist-engine-src/src/backend/conformance/fixtures.rs +26 -0
  19. package/dist-engine-src/src/backend/conformance/mod.rs +75 -0
  20. package/dist-engine-src/src/backend/conformance/model.rs +28 -0
  21. package/dist-engine-src/src/backend/conformance/model_based.rs +257 -0
  22. package/dist-engine-src/src/backend/conformance/persistence.rs +204 -0
  23. package/dist-engine-src/src/backend/conformance/projection.rs +21 -0
  24. package/dist-engine-src/src/backend/conformance/pushdown.rs +24 -0
  25. package/dist-engine-src/src/backend/conformance/runner.rs +90 -0
  26. package/dist-engine-src/src/backend/conformance/scan.rs +24 -0
  27. package/dist-engine-src/src/backend/conformance/write.rs +16 -0
  28. package/dist-engine-src/src/backend/error.rs +94 -0
  29. package/dist-engine-src/src/backend/in_memory.rs +670 -0
  30. package/dist-engine-src/src/backend/mod.rs +36 -9
  31. package/dist-engine-src/src/backend/predicate.rs +80 -0
  32. package/dist-engine-src/src/backend/traits.rs +260 -0
  33. package/dist-engine-src/src/backend/types.rs +224 -81
  34. package/dist-engine-src/src/binary_cas/context.rs +8 -8
  35. package/dist-engine-src/src/binary_cas/kv.rs +234 -259
  36. package/dist-engine-src/src/{version → branch}/context.rs +12 -12
  37. package/dist-engine-src/src/branch/lifecycle.rs +221 -0
  38. package/dist-engine-src/src/branch/mod.rs +13 -0
  39. package/dist-engine-src/src/branch/refs.rs +321 -0
  40. package/dist-engine-src/src/branch/stage_rows.rs +67 -0
  41. package/dist-engine-src/src/branch/types.rs +21 -0
  42. package/dist-engine-src/src/catalog/context.rs +18 -18
  43. package/dist-engine-src/src/catalog/snapshot.rs +8 -8
  44. package/dist-engine-src/src/changelog/bench_support.rs +785 -0
  45. package/dist-engine-src/src/changelog/change.rs +1 -0
  46. package/dist-engine-src/src/changelog/codec.rs +497 -0
  47. package/dist-engine-src/src/changelog/commit.rs +1 -0
  48. package/dist-engine-src/src/changelog/context.rs +1614 -0
  49. package/dist-engine-src/src/changelog/mod.rs +29 -0
  50. package/dist-engine-src/src/changelog/store.rs +163 -0
  51. package/dist-engine-src/src/changelog/test_support.rs +54 -0
  52. package/dist-engine-src/src/changelog/types.rs +213 -0
  53. package/dist-engine-src/src/commit_graph/context.rs +317 -274
  54. package/dist-engine-src/src/commit_graph/mod.rs +2 -4
  55. package/dist-engine-src/src/commit_graph/types.rs +22 -42
  56. package/dist-engine-src/src/commit_graph/walker.rs +133 -103
  57. package/dist-engine-src/src/common/error.rs +52 -18
  58. package/dist-engine-src/src/common/identity.rs +2 -2
  59. package/dist-engine-src/src/common/mod.rs +1 -1
  60. package/dist-engine-src/src/domain.rs +42 -46
  61. package/dist-engine-src/src/engine.rs +74 -96
  62. package/dist-engine-src/src/{entity_identity.rs → entity_pk.rs} +89 -92
  63. package/dist-engine-src/src/functions/context.rs +56 -52
  64. package/dist-engine-src/src/functions/state.rs +51 -52
  65. package/dist-engine-src/src/init.rs +288 -154
  66. package/dist-engine-src/src/json_store/context.rs +15 -266
  67. package/dist-engine-src/src/json_store/mod.rs +26 -0
  68. package/dist-engine-src/src/json_store/store.rs +103 -718
  69. package/dist-engine-src/src/json_store/types.rs +4 -9
  70. package/dist-engine-src/src/lib.rs +49 -19
  71. package/dist-engine-src/src/live_state/context.rs +654 -790
  72. package/dist-engine-src/src/live_state/mod.rs +9 -3
  73. package/dist-engine-src/src/live_state/overlay.rs +4 -4
  74. package/dist-engine-src/src/live_state/types.rs +30 -21
  75. package/dist-engine-src/src/live_state/visibility.rs +514 -71
  76. package/dist-engine-src/src/plugin/install.rs +48 -48
  77. package/dist-engine-src/src/plugin/manifest.rs +7 -7
  78. package/dist-engine-src/src/plugin/materializer.rs +0 -275
  79. package/dist-engine-src/src/plugin/plugin_manifest.json +4 -3
  80. package/dist-engine-src/src/schema/builtin/lix_binary_blob_ref.json +2 -2
  81. package/dist-engine-src/src/schema/builtin/lix_branch_descriptor.json +34 -0
  82. package/dist-engine-src/src/schema/builtin/lix_branch_ref.json +48 -0
  83. package/dist-engine-src/src/schema/builtin/lix_change.json +3 -3
  84. package/dist-engine-src/src/schema/builtin/lix_commit.json +1 -1
  85. package/dist-engine-src/src/schema/builtin/lix_label_assignment.json +6 -6
  86. package/dist-engine-src/src/schema/builtin/mod.rs +18 -20
  87. package/dist-engine-src/src/schema/compatibility.rs +11 -11
  88. package/dist-engine-src/src/schema/definition.json +2 -2
  89. package/dist-engine-src/src/schema/definition.rs +5 -5
  90. package/dist-engine-src/src/schema/key.rs +3 -3
  91. package/dist-engine-src/src/schema/mod.rs +1 -1
  92. package/dist-engine-src/src/schema/tests.rs +18 -18
  93. package/dist-engine-src/src/session/context.rs +803 -148
  94. package/dist-engine-src/src/session/create_branch.rs +94 -0
  95. package/dist-engine-src/src/session/execute.rs +223 -83
  96. package/dist-engine-src/src/session/merge/analysis.rs +9 -3
  97. package/dist-engine-src/src/session/merge/{version.rs → branch.rs} +119 -129
  98. package/dist-engine-src/src/session/merge/conflicts.rs +2 -2
  99. package/dist-engine-src/src/session/merge/mod.rs +5 -6
  100. package/dist-engine-src/src/session/merge/stats.rs +7 -11
  101. package/dist-engine-src/src/session/mod.rs +15 -12
  102. package/dist-engine-src/src/session/switch_branch.rs +113 -0
  103. package/dist-engine-src/src/session/transaction.rs +495 -14
  104. package/dist-engine-src/src/sql2/{classify.rs → bind/classify.rs} +3 -75
  105. package/dist-engine-src/src/sql2/bind/error.rs +5 -0
  106. package/dist-engine-src/src/sql2/bind/expr.rs +29 -0
  107. package/dist-engine-src/src/sql2/bind/mod.rs +12 -0
  108. package/dist-engine-src/src/sql2/{udfs/public_call.rs → bind/public_udf.rs} +71 -3
  109. package/dist-engine-src/src/sql2/bind/read.rs +65 -0
  110. package/dist-engine-src/src/sql2/bind/statement.rs +2236 -0
  111. package/dist-engine-src/src/sql2/bind/table.rs +273 -0
  112. package/dist-engine-src/src/sql2/bind/write.rs +86 -0
  113. package/dist-engine-src/src/sql2/branch_scope.rs +436 -0
  114. package/dist-engine-src/src/sql2/catalog/capability.rs +20 -0
  115. package/dist-engine-src/src/sql2/catalog/entity_surface.rs +296 -0
  116. package/dist-engine-src/src/sql2/catalog/mod.rs +15 -0
  117. package/dist-engine-src/src/sql2/catalog/registry.rs +556 -0
  118. package/dist-engine-src/src/sql2/catalog/schema.rs +88 -0
  119. package/dist-engine-src/src/sql2/catalog/surface.rs +41 -0
  120. package/dist-engine-src/src/sql2/change_materialization.rs +122 -0
  121. package/dist-engine-src/src/sql2/context.rs +36 -30
  122. package/dist-engine-src/src/sql2/error.rs +1 -1
  123. package/dist-engine-src/src/sql2/exec/bound_public_write.rs +1593 -0
  124. package/dist-engine-src/src/sql2/exec/datafusion.rs +5266 -0
  125. package/dist-engine-src/src/sql2/exec/fast_write.rs +82 -0
  126. package/dist-engine-src/src/sql2/exec/mod.rs +24 -0
  127. package/dist-engine-src/src/sql2/exec/write.rs +661 -0
  128. package/dist-engine-src/src/sql2/filesystem_planner.rs +72 -77
  129. package/dist-engine-src/src/sql2/filesystem_visibility.rs +21 -21
  130. package/dist-engine-src/src/sql2/history_projection.rs +8 -8
  131. package/dist-engine-src/src/sql2/history_route.rs +35 -31
  132. package/dist-engine-src/src/sql2/mod.rs +28 -23
  133. package/dist-engine-src/src/sql2/optimize/datafusion.rs +1 -0
  134. package/dist-engine-src/src/sql2/optimize/mod.rs +2 -0
  135. package/dist-engine-src/src/sql2/optimize/simple_write.rs +116 -0
  136. package/dist-engine-src/src/sql2/parse/mod.rs +69 -0
  137. package/dist-engine-src/src/sql2/parse/normalize.rs +1 -0
  138. package/dist-engine-src/src/sql2/plan/branch_scope.rs +24 -0
  139. package/dist-engine-src/src/sql2/plan/mod.rs +5 -0
  140. package/dist-engine-src/src/sql2/plan/predicate.rs +22 -0
  141. package/dist-engine-src/src/sql2/plan/write.rs +147 -0
  142. package/dist-engine-src/src/sql2/predicate_typecheck.rs +258 -0
  143. package/dist-engine-src/src/sql2/{version_provider.rs → providers/branch.rs} +218 -214
  144. package/dist-engine-src/src/sql2/{change_provider.rs → providers/change.rs} +156 -42
  145. package/dist-engine-src/src/sql2/{directory_provider.rs → providers/directory.rs} +291 -322
  146. package/dist-engine-src/src/sql2/{directory_history_provider.rs → providers/directory_history.rs} +56 -42
  147. package/dist-engine-src/src/sql2/providers/entity.rs +1484 -0
  148. package/dist-engine-src/src/sql2/{entity_history_provider.rs → providers/entity_history.rs} +43 -31
  149. package/dist-engine-src/src/sql2/{file_provider.rs → providers/file.rs} +323 -316
  150. package/dist-engine-src/src/sql2/{file_history_provider.rs → providers/file_history.rs} +60 -46
  151. package/dist-engine-src/src/sql2/{history_provider.rs → providers/history.rs} +46 -32
  152. package/dist-engine-src/src/sql2/{lix_state_provider.rs → providers/lix_state.rs} +359 -329
  153. package/dist-engine-src/src/sql2/providers/mod.rs +508 -0
  154. package/dist-engine-src/src/sql2/read_only.rs +2 -2
  155. package/dist-engine-src/src/sql2/session.rs +47 -96
  156. package/dist-engine-src/src/sql2/storage/constraints.rs +1 -0
  157. package/dist-engine-src/src/sql2/storage/mod.rs +1 -0
  158. package/dist-engine-src/src/sql2/test_support/differential.rs +712 -0
  159. package/dist-engine-src/src/sql2/test_support/generators.rs +354 -0
  160. package/dist-engine-src/src/sql2/test_support/mod.rs +2 -0
  161. package/dist-engine-src/src/sql2/udfs/{lix_active_version_commit_id.rs → lix_active_branch_commit_id.rs} +7 -7
  162. package/dist-engine-src/src/sql2/udfs/mod.rs +3 -6
  163. package/dist-engine-src/src/sql2/write_normalization.rs +45 -22
  164. package/dist-engine-src/src/storage/conformance.rs +399 -0
  165. package/dist-engine-src/src/storage/context.rs +552 -288
  166. package/dist-engine-src/src/storage/mod.rs +48 -10
  167. package/dist-engine-src/src/storage/point.rs +440 -0
  168. package/dist-engine-src/src/storage/read_scope.rs +43 -64
  169. package/dist-engine-src/src/storage/reader.rs +867 -0
  170. package/dist-engine-src/src/storage/scan.rs +784 -0
  171. package/dist-engine-src/src/storage/spaces.rs +236 -0
  172. package/dist-engine-src/src/storage/stats.rs +80 -0
  173. package/dist-engine-src/src/storage/write_set.rs +962 -0
  174. package/dist-engine-src/src/storage_bench.rs +136 -4828
  175. package/dist-engine-src/src/test_support.rs +360 -138
  176. package/dist-engine-src/src/tracked_state/bench_support.rs +394 -0
  177. package/dist-engine-src/src/tracked_state/codec.rs +155 -1057
  178. package/dist-engine-src/src/tracked_state/commit_root_rebuild.rs +358 -0
  179. package/dist-engine-src/src/tracked_state/context.rs +1927 -993
  180. package/dist-engine-src/src/tracked_state/diff.rs +1715 -261
  181. package/dist-engine-src/src/tracked_state/merge.rs +74 -88
  182. package/dist-engine-src/src/tracked_state/mod.rs +19 -16
  183. package/dist-engine-src/src/tracked_state/{materialization.rs → row_materialization.rs} +50 -178
  184. package/dist-engine-src/src/tracked_state/storage.rs +243 -191
  185. package/dist-engine-src/src/tracked_state/tree.rs +247 -371
  186. package/dist-engine-src/src/tracked_state/types.rs +49 -42
  187. package/dist-engine-src/src/transaction/bench_support.rs +407 -0
  188. package/dist-engine-src/src/transaction/commit.rs +821 -713
  189. package/dist-engine-src/src/transaction/context.rs +705 -600
  190. package/dist-engine-src/src/transaction/mod.rs +13 -2
  191. package/dist-engine-src/src/transaction/normalization.rs +63 -76
  192. package/dist-engine-src/src/transaction/prep.rs +13 -13
  193. package/dist-engine-src/src/transaction/schema_resolver.rs +19 -5
  194. package/dist-engine-src/src/transaction/staging.rs +228 -434
  195. package/dist-engine-src/src/transaction/types.rs +41 -98
  196. package/dist-engine-src/src/transaction/validation.rs +382 -446
  197. package/dist-engine-src/src/untracked_state/codec.rs +337 -29
  198. package/dist-engine-src/src/untracked_state/context.rs +7 -7
  199. package/dist-engine-src/src/untracked_state/materialization.rs +2 -2
  200. package/dist-engine-src/src/untracked_state/mod.rs +1 -1
  201. package/dist-engine-src/src/untracked_state/storage.rs +659 -157
  202. package/dist-engine-src/src/untracked_state/types.rs +21 -21
  203. package/package.json +71 -68
  204. package/dist-engine-src/src/backend/kv.rs +0 -358
  205. package/dist-engine-src/src/backend/testing.rs +0 -658
  206. package/dist-engine-src/src/commit_store/codec.rs +0 -887
  207. package/dist-engine-src/src/commit_store/context.rs +0 -944
  208. package/dist-engine-src/src/commit_store/materialization.rs +0 -84
  209. package/dist-engine-src/src/commit_store/mod.rs +0 -16
  210. package/dist-engine-src/src/commit_store/storage.rs +0 -600
  211. package/dist-engine-src/src/commit_store/types.rs +0 -215
  212. package/dist-engine-src/src/schema/builtin/lix_version_descriptor.json +0 -34
  213. package/dist-engine-src/src/schema/builtin/lix_version_ref.json +0 -48
  214. package/dist-engine-src/src/session/create_version.rs +0 -88
  215. package/dist-engine-src/src/session/merge/apply.rs +0 -23
  216. package/dist-engine-src/src/session/optimization9_sql2_bench.rs +0 -100
  217. package/dist-engine-src/src/session/switch_version.rs +0 -110
  218. package/dist-engine-src/src/sql2/entity_provider.rs +0 -3211
  219. package/dist-engine-src/src/sql2/execute.rs +0 -3533
  220. package/dist-engine-src/src/sql2/public_bind/assignment.rs +0 -46
  221. package/dist-engine-src/src/sql2/public_bind/capability.rs +0 -41
  222. package/dist-engine-src/src/sql2/public_bind/dml.rs +0 -172
  223. package/dist-engine-src/src/sql2/public_bind/mod.rs +0 -26
  224. package/dist-engine-src/src/sql2/public_bind/table.rs +0 -168
  225. package/dist-engine-src/src/sql2/version_scope.rs +0 -394
  226. package/dist-engine-src/src/storage/types.rs +0 -501
  227. package/dist-engine-src/src/tracked_state/by_file_index.rs +0 -98
  228. package/dist-engine-src/src/tracked_state/materializer.rs +0 -488
  229. package/dist-engine-src/src/transaction/live_state_overlay.rs +0 -35
  230. package/dist-engine-src/src/version/lifecycle.rs +0 -221
  231. package/dist-engine-src/src/version/mod.rs +0 -13
  232. package/dist-engine-src/src/version/refs.rs +0 -330
  233. package/dist-engine-src/src/version/stage_rows.rs +0 -67
  234. package/dist-engine-src/src/version/types.rs +0 -21
@@ -1,6 +1,7 @@
1
+ #[cfg(feature = "storage-benches")]
2
+ mod bench_support;
1
3
  mod commit;
2
4
  mod context;
3
- mod live_state_overlay;
4
5
  mod normalization;
5
6
  mod prep;
6
7
  mod schema_resolver;
@@ -8,6 +9,16 @@ mod staging;
8
9
  pub(crate) mod types;
9
10
  mod validation;
10
11
 
12
+ #[cfg(feature = "storage-benches")]
13
+ pub mod bench {
14
+ pub use super::bench_support::*;
15
+ }
16
+
17
+ pub(crate) use context::begin_commit_boundary;
18
+ pub(crate) use context::commit_at_boundary;
11
19
  pub(crate) use context::open_transaction;
20
+ pub(crate) use context::CommitBoundaryGuard;
21
+ pub(crate) use context::CommitBoundaryState;
12
22
  pub(crate) use context::Transaction;
13
- pub(crate) use prep::prepare_version_ref_row;
23
+ pub(crate) use context::TransactionCommitBoundary;
24
+ pub(crate) use prep::prepare_branch_ref_row;
@@ -6,7 +6,7 @@ use crate::catalog::{CatalogSnapshot, SchemaPlan, SchemaPlanId};
6
6
  use crate::common::format_json_pointer;
7
7
  use crate::common::normalize_path_segment;
8
8
  use crate::domain::Domain;
9
- use crate::entity_identity::{EntityIdentity, EntityIdentityError};
9
+ use crate::entity_pk::{EntityPk, EntityPkError};
10
10
  use crate::functions::FunctionProviderHandle;
11
11
  use crate::schema::{
12
12
  is_seed_schema_key, schema_from_registered_snapshot, validate_lix_schema,
@@ -27,7 +27,7 @@ pub(crate) struct NormalizedTransactionWriteRow {
27
27
  pub(crate) facts: PreparedRowFacts,
28
28
  }
29
29
 
30
- /// Normalizes one incoming row into a row with final snapshot/entity identity.
30
+ /// Normalizes one incoming row into a row with final snapshot/entity primary key.
31
31
  ///
32
32
  /// This is the canonical schema-semantics boundary for transaction writes. It owns
33
33
  /// schema default application, primary-key identity derivation, and explicit
@@ -60,7 +60,7 @@ pub(crate) fn normalize_transaction_write_row(
60
60
  let defaults_changed = apply_defaults(&mut snapshot, schema_plan, &row, functions)?;
61
61
  let descriptor_changed = normalize_filesystem_descriptor_snapshot(&row, &mut snapshot)?;
62
62
  let snapshot = JsonValue::Object(snapshot);
63
- row.entity_id = Some(resolve_entity_id(&row, schema_plan, &snapshot)?);
63
+ row.entity_pk = Some(resolve_entity_pk(&row, schema_plan, &snapshot)?);
64
64
  if defaults_changed || descriptor_changed {
65
65
  Some(TransactionJson::from_value(
66
66
  snapshot,
@@ -69,11 +69,11 @@ pub(crate) fn normalize_transaction_write_row(
69
69
  } else {
70
70
  Some(TransactionJson::from_parts(Arc::new(snapshot), normalized))
71
71
  }
72
- } else if row.entity_id.is_none() {
72
+ } else if row.entity_pk.is_none() {
73
73
  return Err(LixError::new(
74
74
  LixError::CODE_SCHEMA_VALIDATION,
75
75
  format!(
76
- "tombstone for schema '{}' requires entity_id",
76
+ "tombstone for schema '{}' requires entity_pk",
77
77
  row.schema_key
78
78
  ),
79
79
  ));
@@ -87,10 +87,10 @@ pub(crate) fn normalize_transaction_write_row(
87
87
  LixError::CODE_SCHEMA_DEFINITION,
88
88
  "lix_registered_schema rows must not be scoped to a file",
89
89
  )
90
- .with_hint("Schema definitions are scoped by version and durability only; write them with null file_id."));
90
+ .with_hint("Schema definitions are scoped by branch and durability only; write them with null file_id."));
91
91
  }
92
92
  let schema_domain =
93
- Domain::schema_catalog(row.schema_scope_version_id().to_string(), row.untracked);
93
+ Domain::schema_catalog(row.schema_scope_branch_id().to_string(), row.untracked);
94
94
  remember_pending_registered_schema(
95
95
  normalized_snapshot.as_ref().map(TransactionJson::value),
96
96
  schema_domain,
@@ -210,31 +210,31 @@ fn optional_string_field<'a>(
210
210
  })
211
211
  }
212
212
 
213
- fn resolve_entity_id(
213
+ fn resolve_entity_pk(
214
214
  row: &TransactionWriteRow,
215
215
  schema_plan: &SchemaPlan,
216
216
  snapshot: &JsonValue,
217
- ) -> Result<EntityIdentity, LixError> {
217
+ ) -> Result<EntityPk, LixError> {
218
218
  let Some(primary_key_paths) = schema_plan.primary_key.as_ref() else {
219
- return row.entity_id.clone().ok_or_else(|| {
219
+ return row.entity_pk.clone().ok_or_else(|| {
220
220
  LixError::new(
221
221
  LixError::CODE_SCHEMA_VALIDATION,
222
222
  format!(
223
- "write for schema '{}' requires entity_id because the schema has no x-lix-primary-key",
223
+ "write for schema '{}' requires entity_pk because the schema has no x-lix-primary-key",
224
224
  row.schema_key
225
225
  ),
226
226
  )
227
227
  });
228
228
  };
229
- let derived = EntityIdentity::from_primary_key_paths(snapshot, primary_key_paths)
230
- .map_err(|error| entity_id_derivation_error(row, primary_key_paths, error))?;
231
- if let Some(entity_id) = row.entity_id.as_ref() {
232
- if entity_id != &derived {
229
+ let derived = EntityPk::from_primary_key_paths(snapshot, primary_key_paths)
230
+ .map_err(|error| entity_pk_derivation_error(row, primary_key_paths, error))?;
231
+ if let Some(entity_pk) = row.entity_pk.as_ref() {
232
+ if entity_pk != &derived {
233
233
  return Err(LixError::new(
234
234
  LixError::CODE_SCHEMA_VALIDATION,
235
235
  format!(
236
- "entity_id '{}' does not match x-lix-primary-key derived entity_id '{}' for schema '{}'",
237
- entity_id.as_json_array_text()?, derived.as_json_array_text()?, row.schema_key
236
+ "entity_pk '{}' does not match x-lix-primary-key derived entity_pk '{}' for schema '{}'",
237
+ entity_pk.as_json_array_text()?, derived.as_json_array_text()?, row.schema_key
238
238
  ),
239
239
  ));
240
240
  }
@@ -242,39 +242,30 @@ fn resolve_entity_id(
242
242
  Ok(derived)
243
243
  }
244
244
 
245
- fn entity_id_derivation_error(
245
+ fn entity_pk_derivation_error(
246
246
  row: &TransactionWriteRow,
247
247
  primary_key_paths: &[Vec<String>],
248
- error: EntityIdentityError,
248
+ error: EntityPkError,
249
249
  ) -> LixError {
250
250
  let detail = match error {
251
- EntityIdentityError::EmptyPrimaryKey => "empty x-lix-primary-key".to_string(),
252
- EntityIdentityError::EmptyPrimaryKeyPath { index } => {
251
+ EntityPkError::EmptyPrimaryKey => "empty x-lix-primary-key".to_string(),
252
+ EntityPkError::EmptyPrimaryKeyPath { index } => {
253
253
  format!("empty x-lix-primary-key pointer at index {index}")
254
254
  }
255
- EntityIdentityError::EmptyPrimaryKeyValue { index } => {
256
- let pointer = primary_key_paths
257
- .get(index)
258
- .map(|path| format_json_pointer(path))
259
- .unwrap_or_else(|| format!("index {index}"));
260
- format!("empty value at primary-key pointer '{pointer}'")
261
- }
262
- EntityIdentityError::MissingPrimaryKeyValue { index } => {
255
+ EntityPkError::MissingPrimaryKeyValue { index } => {
263
256
  let pointer = format_json_pointer(&primary_key_paths[index]);
264
257
  format!("missing value at primary-key pointer '{pointer}'")
265
258
  }
266
- EntityIdentityError::UnsupportedPrimaryKeyValue { index } => {
259
+ EntityPkError::UnsupportedPrimaryKeyValue { index } => {
267
260
  let pointer = format_json_pointer(&primary_key_paths[index]);
268
261
  format!("non-string value at primary-key pointer '{pointer}'")
269
262
  }
270
- EntityIdentityError::InvalidEncodedEntityIdentity => {
271
- "invalid encoded entity identity".to_string()
272
- }
263
+ EntityPkError::InvalidEncodedEntityPk => "invalid encoded entity primary key".to_string(),
273
264
  };
274
265
  LixError::new(
275
266
  LixError::CODE_SCHEMA_VALIDATION,
276
267
  format!(
277
- "failed to derive entity_id for schema '{}': {detail}",
268
+ "failed to derive entity_pk for schema '{}': {detail}",
278
269
  row.schema_key
279
270
  ),
280
271
  )
@@ -329,10 +320,10 @@ mod tests {
329
320
  use crate::schema::seed_schema_definition;
330
321
 
331
322
  #[test]
332
- fn normalization_derives_entity_id_from_primary_key() {
323
+ fn normalization_derives_entity_pk_from_primary_key() {
333
324
  let mut catalog = catalog_with(vec![schema_with_default_id()]);
334
325
  let row = TransactionWriteRow {
335
- entity_id: None,
326
+ entity_pk: None,
336
327
  schema_key: "normalization_schema".to_string(),
337
328
  snapshot: Some(snapshot_json(
338
329
  r#"{"id":"entity-from-snapshot","value":"hello"}"#,
@@ -344,10 +335,8 @@ mod tests {
344
335
  normalize_transaction_write_row(row, &mut catalog, functions()).expect("normalize row");
345
336
 
346
337
  assert_eq!(
347
- row.row.entity_id.as_ref(),
348
- Some(&crate::entity_identity::EntityIdentity::single(
349
- "entity-from-snapshot"
350
- ))
338
+ row.row.entity_pk.as_ref(),
339
+ Some(&crate::entity_pk::EntityPk::single("entity-from-snapshot"))
351
340
  );
352
341
  }
353
342
 
@@ -355,7 +344,7 @@ mod tests {
355
344
  fn normalization_applies_json_and_cel_defaults_before_identity_derivation() {
356
345
  let mut catalog = catalog_with(vec![schema_with_default_id()]);
357
346
  let row = TransactionWriteRow {
358
- entity_id: None,
347
+ entity_pk: None,
359
348
  schema_key: "normalization_schema".to_string(),
360
349
  snapshot: Some(snapshot_json(r#"{}"#)),
361
350
  ..base_stage_row()
@@ -366,10 +355,8 @@ mod tests {
366
355
  let snapshot = normalized_snapshot(&row);
367
356
 
368
357
  assert_eq!(
369
- row.row.entity_id.as_ref(),
370
- Some(&crate::entity_identity::EntityIdentity::single(
371
- "uuid-default"
372
- ))
358
+ row.row.entity_pk.as_ref(),
359
+ Some(&crate::entity_pk::EntityPk::single("uuid-default"))
373
360
  );
374
361
  assert_eq!(snapshot["id"], "uuid-default");
375
362
  assert_eq!(snapshot["value"], "literal-default");
@@ -379,7 +366,7 @@ mod tests {
379
366
  fn normalization_applies_cel_defaults_from_snapshot_context() {
380
367
  let mut catalog = catalog_with(vec![schema_with_cel_field_default()]);
381
368
  let row = TransactionWriteRow {
382
- entity_id: None,
369
+ entity_pk: None,
383
370
  schema_key: "cel_field_default_schema".to_string(),
384
371
  snapshot: Some(snapshot_json(r#"{"id":"entity-1","name":"Sample"}"#)),
385
372
  ..base_stage_row()
@@ -396,7 +383,7 @@ mod tests {
396
383
  fn normalization_x_lix_default_overrides_json_default() {
397
384
  let mut catalog = catalog_with(vec![schema_with_overridden_default()]);
398
385
  let row = TransactionWriteRow {
399
- entity_id: None,
386
+ entity_pk: None,
400
387
  schema_key: "overridden_default_schema".to_string(),
401
388
  snapshot: Some(snapshot_json(r#"{"id":"entity-1"}"#)),
402
389
  ..base_stage_row()
@@ -413,7 +400,7 @@ mod tests {
413
400
  fn normalization_does_not_overwrite_explicit_null_with_default() {
414
401
  let mut catalog = catalog_with(vec![schema_with_nullable_default()]);
415
402
  let row = TransactionWriteRow {
416
- entity_id: None,
403
+ entity_pk: None,
417
404
  schema_key: "nullable_default_schema".to_string(),
418
405
  snapshot: Some(snapshot_json(r#"{"id":"entity-1","status":null}"#)),
419
406
  ..base_stage_row()
@@ -430,7 +417,7 @@ mod tests {
430
417
  fn normalization_applies_timestamp_function_default() {
431
418
  let mut catalog = catalog_with(vec![schema_with_timestamp_default()]);
432
419
  let row = TransactionWriteRow {
433
- entity_id: None,
420
+ entity_pk: None,
434
421
  schema_key: "timestamp_default_schema".to_string(),
435
422
  snapshot: Some(snapshot_json(r#"{"id":"entity-1"}"#)),
436
423
  ..base_stage_row()
@@ -447,7 +434,7 @@ mod tests {
447
434
  fn normalization_surfaces_cel_default_errors() {
448
435
  let mut catalog = catalog_with(vec![schema_with_unknown_cel_default()]);
449
436
  let row = TransactionWriteRow {
450
- entity_id: None,
437
+ entity_pk: None,
451
438
  schema_key: "unknown_cel_default_schema".to_string(),
452
439
  snapshot: Some(snapshot_json(r#"{"id":"entity-1"}"#)),
453
440
  ..base_stage_row()
@@ -461,10 +448,10 @@ mod tests {
461
448
  }
462
449
 
463
450
  #[test]
464
- fn normalization_rejects_entity_id_that_disagrees_with_primary_key() {
451
+ fn normalization_rejects_entity_pk_that_disagrees_with_primary_key() {
465
452
  let mut catalog = catalog_with(vec![schema_with_default_id()]);
466
453
  let row = TransactionWriteRow {
467
- entity_id: Some(crate::entity_identity::EntityIdentity::single("wrong-id")),
454
+ entity_pk: Some(crate::entity_pk::EntityPk::single("wrong-id")),
468
455
  schema_key: "normalization_schema".to_string(),
469
456
  snapshot: Some(snapshot_json(r#"{"id":"right-id","value":"hello"}"#)),
470
457
  ..base_stage_row()
@@ -475,14 +462,14 @@ mod tests {
475
462
 
476
463
  assert!(error
477
464
  .message
478
- .contains("does not match x-lix-primary-key derived entity_id"));
465
+ .contains("does not match x-lix-primary-key derived entity_pk"));
479
466
  }
480
467
 
481
468
  #[test]
482
- fn normalization_derives_json_array_entity_id_for_composite_primary_key() {
469
+ fn normalization_derives_json_array_entity_pk_for_composite_primary_key() {
483
470
  let mut catalog = catalog_with(vec![composite_key_schema()]);
484
471
  let row = TransactionWriteRow {
485
- entity_id: None,
472
+ entity_pk: None,
486
473
  schema_key: "composite_key_schema".to_string(),
487
474
  snapshot: Some(snapshot_json(r#"{"namespace":"a~b","key":"1"}"#)),
488
475
  ..base_stage_row()
@@ -490,19 +477,19 @@ mod tests {
490
477
 
491
478
  let row =
492
479
  normalize_transaction_write_row(row, &mut catalog, functions()).expect("normalize row");
493
- let entity_id = row.row.entity_id.expect("composite entity id");
494
- let projected_entity_id = entity_id
480
+ let entity_pk = row.row.entity_pk.expect("composite entity pk");
481
+ let projected_entity_pk = entity_pk
495
482
  .as_json_array_text()
496
- .expect("entity id should project");
483
+ .expect("entity pk should project");
497
484
 
498
- assert_eq!(projected_entity_id, "[\"a~b\",\"1\"]");
485
+ assert_eq!(projected_entity_pk, "[\"a~b\",\"1\"]");
499
486
  }
500
487
 
501
488
  #[test]
502
489
  fn normalization_rejects_non_string_primary_key_values() {
503
490
  let mut catalog = catalog_with(vec![composite_key_schema()]);
504
491
  let row = TransactionWriteRow {
505
- entity_id: None,
492
+ entity_pk: None,
506
493
  schema_key: "composite_key_schema".to_string(),
507
494
  snapshot: Some(snapshot_json(r#"{"namespace":"a~b","key":1}"#)),
508
495
  ..base_stage_row()
@@ -518,19 +505,19 @@ mod tests {
518
505
  }
519
506
 
520
507
  #[test]
521
- fn normalization_validates_explicit_composite_entity_id_against_projection() {
508
+ fn normalization_validates_explicit_composite_entity_pk_against_projection() {
522
509
  let mut catalog = catalog_with(vec![composite_key_schema()]);
523
510
  let snapshot = json!({
524
511
  "namespace": "a~b",
525
512
  "key": "1",
526
513
  });
527
- let derived = EntityIdentity::from_primary_key_paths(
514
+ let derived = EntityPk::from_primary_key_paths(
528
515
  &snapshot,
529
516
  &[vec!["namespace".to_string()], vec!["key".to_string()]],
530
517
  )
531
518
  .expect("identity should derive");
532
519
  let row = TransactionWriteRow {
533
- entity_id: Some(derived.clone()),
520
+ entity_pk: Some(derived.clone()),
534
521
  schema_key: "composite_key_schema".to_string(),
535
522
  snapshot: Some(transaction_json(snapshot.clone())),
536
523
  ..base_stage_row()
@@ -539,7 +526,7 @@ mod tests {
539
526
  let row =
540
527
  normalize_transaction_write_row(row, &mut catalog, functions()).expect("normalize row");
541
528
 
542
- assert_eq!(row.row.entity_id.as_ref(), Some(&derived));
529
+ assert_eq!(row.row.entity_pk.as_ref(), Some(&derived));
543
530
  }
544
531
 
545
532
  #[test]
@@ -548,7 +535,7 @@ mod tests {
548
535
  .expect("registered schema builtin")
549
536
  .clone()]);
550
537
  let registered = TransactionWriteRow {
551
- entity_id: None,
538
+ entity_pk: None,
552
539
  schema_key: REGISTERED_SCHEMA_KEY.to_string(),
553
540
  snapshot: Some(transaction_json(json!({
554
541
  "value": dynamic_schema_definition(),
@@ -560,7 +547,7 @@ mod tests {
560
547
  .expect("register schema");
561
548
 
562
549
  let dynamic = TransactionWriteRow {
563
- entity_id: None,
550
+ entity_pk: None,
564
551
  schema_key: "dynamic_schema".to_string(),
565
552
  snapshot: Some(snapshot_json(r#"{"id":"dynamic-1"}"#)),
566
553
  ..base_stage_row()
@@ -569,8 +556,8 @@ mod tests {
569
556
  .expect("dynamic row");
570
557
 
571
558
  assert_eq!(
572
- dynamic.row.entity_id.as_ref(),
573
- Some(&crate::entity_identity::EntityIdentity::single("dynamic-1"))
559
+ dynamic.row.entity_pk.as_ref(),
560
+ Some(&crate::entity_pk::EntityPk::single("dynamic-1"))
574
561
  );
575
562
  }
576
563
 
@@ -582,7 +569,7 @@ mod tests {
582
569
  ]);
583
570
 
584
571
  let file = TransactionWriteRow {
585
- entity_id: None,
572
+ entity_pk: None,
586
573
  schema_key: FILE_DESCRIPTOR_SCHEMA_KEY.to_string(),
587
574
  snapshot: Some(transaction_json(json!({
588
575
  "id": "file-cafe",
@@ -598,7 +585,7 @@ mod tests {
598
585
  assert_eq!(file_snapshot["name"], "Café.txt");
599
586
 
600
587
  let directory = TransactionWriteRow {
601
- entity_id: None,
588
+ entity_pk: None,
602
589
  schema_key: DIRECTORY_DESCRIPTOR_SCHEMA_KEY.to_string(),
603
590
  snapshot: Some(transaction_json(json!({
604
591
  "id": "dir-cafe",
@@ -623,7 +610,7 @@ mod tests {
623
610
 
624
611
  let dot_segment = normalize_transaction_write_row(
625
612
  TransactionWriteRow {
626
- entity_id: None,
613
+ entity_pk: None,
627
614
  schema_key: FILE_DESCRIPTOR_SCHEMA_KEY.to_string(),
628
615
  snapshot: Some(transaction_json(json!({
629
616
  "id": "file-dotdot",
@@ -641,7 +628,7 @@ mod tests {
641
628
 
642
629
  let bidi = normalize_transaction_write_row(
643
630
  TransactionWriteRow {
644
- entity_id: None,
631
+ entity_pk: None,
645
632
  schema_key: FILE_DESCRIPTOR_SCHEMA_KEY.to_string(),
646
633
  snapshot: Some(transaction_json(json!({
647
634
  "id": "file-bidi",
@@ -659,7 +646,7 @@ mod tests {
659
646
 
660
647
  let zero_width = normalize_transaction_write_row(
661
648
  TransactionWriteRow {
662
- entity_id: None,
649
+ entity_pk: None,
663
650
  schema_key: DIRECTORY_DESCRIPTOR_SCHEMA_KEY.to_string(),
664
651
  snapshot: Some(transaction_json(json!({
665
652
  "id": "dir-zero-width",
@@ -682,7 +669,7 @@ mod tests {
682
669
 
683
670
  let row = normalize_transaction_write_row(
684
671
  TransactionWriteRow {
685
- entity_id: None,
672
+ entity_pk: None,
686
673
  schema_key: FILE_DESCRIPTOR_SCHEMA_KEY.to_string(),
687
674
  snapshot: Some(transaction_json(json!({
688
675
  "id": "file-opaque-name",
@@ -737,7 +724,7 @@ mod tests {
737
724
 
738
725
  fn base_stage_row() -> TransactionWriteRow {
739
726
  TransactionWriteRow {
740
- entity_id: Some(crate::entity_identity::EntityIdentity::single("entity-1")),
727
+ entity_pk: Some(crate::entity_pk::EntityPk::single("entity-1")),
741
728
  schema_key: "normalization_schema".to_string(),
742
729
  file_id: None,
743
730
  snapshot: Some(snapshot_json(r#"{"id":"entity-1","value":"hello"}"#)),
@@ -749,7 +736,7 @@ mod tests {
749
736
  change_id: None,
750
737
  commit_id: None,
751
738
  untracked: false,
752
- version_id: crate::GLOBAL_VERSION_ID.to_string(),
739
+ branch_id: crate::GLOBAL_BRANCH_ID.to_string(),
753
740
  }
754
741
  }
755
742
 
@@ -1,37 +1,37 @@
1
- use crate::entity_identity::EntityIdentity;
1
+ use crate::branch::BRANCH_REF_SCHEMA_KEY;
2
+ use crate::entity_pk::EntityPk;
2
3
  use crate::untracked_state::UntrackedStateRow;
3
- use crate::version::VERSION_REF_SCHEMA_KEY;
4
- use crate::{LixError, GLOBAL_VERSION_ID};
4
+ use crate::{LixError, GLOBAL_BRANCH_ID};
5
5
 
6
- pub(crate) struct PreparedVersionRefRow {
6
+ pub(crate) struct PreparedBranchRefRow {
7
7
  pub(crate) row: UntrackedStateRow,
8
8
  }
9
9
 
10
- pub(crate) fn prepare_version_ref_row(
11
- version_id: &str,
10
+ pub(crate) fn prepare_branch_ref_row(
11
+ branch_id: &str,
12
12
  commit_id: &str,
13
13
  timestamp: &str,
14
- ) -> Result<PreparedVersionRefRow, LixError> {
14
+ ) -> Result<PreparedBranchRefRow, LixError> {
15
15
  let snapshot = serde_json::json!({
16
- "id": version_id,
16
+ "id": branch_id,
17
17
  "commit_id": commit_id,
18
18
  });
19
19
  let snapshot = crate::json_store::NormalizedJson::from_value(
20
20
  &snapshot,
21
- "engine version-ref snapshot_content",
21
+ "engine branch-ref snapshot_content",
22
22
  )?;
23
23
 
24
- Ok(PreparedVersionRefRow {
24
+ Ok(PreparedBranchRefRow {
25
25
  row: UntrackedStateRow {
26
- entity_id: EntityIdentity::single(version_id),
27
- schema_key: VERSION_REF_SCHEMA_KEY.to_string(),
26
+ entity_pk: EntityPk::single(branch_id),
27
+ schema_key: BRANCH_REF_SCHEMA_KEY.to_string(),
28
28
  file_id: None,
29
29
  snapshot_content: Some(snapshot.as_str().to_string()),
30
30
  metadata: None,
31
31
  created_at: timestamp.to_string(),
32
32
  updated_at: timestamp.to_string(),
33
33
  global: true,
34
- version_id: GLOBAL_VERSION_ID.to_string(),
34
+ branch_id: GLOBAL_BRANCH_ID.to_string(),
35
35
  },
36
36
  })
37
37
  }
@@ -6,9 +6,9 @@ use async_trait::async_trait;
6
6
  use crate::catalog::{CatalogContext, CatalogSnapshot, SchemaCatalogFact};
7
7
  use crate::domain::Domain;
8
8
  use crate::live_state::{
9
- LiveStateReader, LiveStateRowRequest, LiveStateScanRequest, MaterializedLiveStateRow,
9
+ overlay_scan_rows, LiveStateReader, LiveStateRowRequest, LiveStateScanRequest,
10
+ MaterializedLiveStateRow,
10
11
  };
11
- use crate::transaction::live_state_overlay::overlay_scan_rows;
12
12
  use crate::transaction::staging::PreparedStateRowOverlay;
13
13
  use crate::LixError;
14
14
 
@@ -89,7 +89,7 @@ impl TransactionSchemaResolver {
89
89
  match self
90
90
  .catalogs_by_domain
91
91
  .get_mut(&domain)
92
- .expect("catalog cache should contain requested version")
92
+ .expect("catalog cache should contain requested branch")
93
93
  {
94
94
  CatalogEntry::Catalog(catalog) => Ok(catalog),
95
95
  CatalogEntry::SchemaFacts(_) => {
@@ -109,7 +109,7 @@ impl TransactionSchemaResolver {
109
109
  match self
110
110
  .catalogs_by_domain
111
111
  .get(&domain)
112
- .expect("catalog cache should contain requested version")
112
+ .expect("catalog cache should contain requested branch")
113
113
  {
114
114
  CatalogEntry::Catalog(catalog) => Ok(catalog),
115
115
  CatalogEntry::SchemaFacts(_) => {
@@ -144,6 +144,20 @@ impl LiveStateReader for TransactionSchemaLiveStateReader<'_> {
144
144
  &self,
145
145
  request: &LiveStateRowRequest,
146
146
  ) -> Result<Option<MaterializedLiveStateRow>, LixError> {
147
- self.base.load_row(request).await
147
+ Ok(self
148
+ .scan_rows(&LiveStateScanRequest {
149
+ filter: crate::live_state::LiveStateFilter {
150
+ schema_keys: vec![request.schema_key.clone()],
151
+ entity_pks: vec![request.entity_pk.clone()],
152
+ branch_ids: vec![request.branch_id.clone()],
153
+ file_ids: vec![request.file_id.clone()],
154
+ ..Default::default()
155
+ },
156
+ limit: Some(1),
157
+ ..Default::default()
158
+ })
159
+ .await?
160
+ .into_iter()
161
+ .next())
148
162
  }
149
163
  }