@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,48 +1,49 @@
1
1
  use std::sync::Arc;
2
2
 
3
3
  use crate::binary_cas::BinaryCasContext;
4
+ use crate::branch::{BranchContext, BranchRefReader};
4
5
  use crate::catalog::CatalogContext;
5
6
  use crate::commit_graph::CommitGraphContext;
6
- use crate::commit_store::CommitStoreContext;
7
- use crate::entity_identity::EntityIdentity;
7
+ use crate::entity_pk::EntityPk;
8
8
  use crate::init::InitReceipt;
9
9
  use crate::live_state::LiveStateContext;
10
10
  use crate::live_state::LiveStateRowRequest;
11
11
  use crate::session::SessionContext;
12
+ use crate::storage::{DurableWriteLock, StorageBackend, StorageReadOptions, StorageWriteOptions};
12
13
  use crate::storage::{StorageContext, StorageWriteSet};
13
14
  use crate::tracked_state::TrackedStateContext;
14
15
  use crate::untracked_state::UntrackedStateContext;
15
- use crate::version::{VersionContext, VersionRefReader};
16
- use crate::GLOBAL_VERSION_ID;
17
- use crate::{Backend, LixError, NullableKeyFilter};
16
+ use crate::GLOBAL_BRANCH_ID;
17
+ use crate::{LixError, NullableKeyFilter};
18
18
 
19
19
  #[derive(Clone)]
20
- pub struct Engine {
21
- storage: StorageContext,
20
+ pub struct Engine<B: StorageBackend = crate::storage::InMemoryStorageBackend> {
21
+ storage: StorageContext<B>,
22
22
  tracked_state: Arc<TrackedStateContext>,
23
23
  live_state: Arc<LiveStateContext>,
24
- version_ctx: Arc<VersionContext>,
24
+ branch_ctx: Arc<BranchContext>,
25
25
  binary_cas: Arc<BinaryCasContext>,
26
- commit_store: Arc<CommitStoreContext>,
27
26
  catalog_context: Arc<CatalogContext>,
27
+ write_lock: DurableWriteLock,
28
28
  }
29
29
 
30
- impl Engine {
30
+ impl<B> Engine<B>
31
+ where
32
+ B: StorageBackend + Clone + Send + Sync + 'static,
33
+ for<'backend> B::Read<'backend>: Clone + Send + Sync + 'static,
34
+ for<'backend> B::Write<'backend>: Send,
35
+ {
31
36
  /// Seeds an empty backend with the engine repository bootstrap facts.
32
37
  ///
33
38
  /// Initialization is a storage lifecycle operation, separate from runtime
34
39
  /// construction. Call this before `Engine::new(...)` for a brand-new
35
40
  /// backend.
36
- pub async fn initialize(
37
- backend: Box<dyn Backend + Send + Sync>,
38
- ) -> Result<InitReceipt, LixError> {
39
- let backend: Arc<dyn Backend + Send + Sync> = Arc::from(backend);
41
+ pub async fn initialize(backend: B) -> Result<InitReceipt, LixError> {
40
42
  let storage = StorageContext::new(backend);
41
- let commit_store = CommitStoreContext::new();
43
+ let _write_guard = storage.durable_write_lock().lock_owned().await;
42
44
 
43
45
  crate::init::initialize(
44
46
  storage,
45
- &commit_store,
46
47
  &TrackedStateContext::new(),
47
48
  &UntrackedStateContext::new(),
48
49
  )
@@ -53,20 +54,18 @@ impl Engine {
53
54
  ///
54
55
  /// SessionContext, execution, and transaction overlays are layered below the
55
56
  /// instance instead of being hidden behind a legacy boot path.
56
- pub async fn new(backend: Box<dyn Backend + Send + Sync>) -> Result<Self, LixError> {
57
- let backend: Arc<dyn Backend + Send + Sync> = Arc::from(backend);
57
+ pub async fn new(backend: B) -> Result<Self, LixError> {
58
58
  let storage = StorageContext::new(backend);
59
59
 
60
60
  let tracked_state = Arc::new(TrackedStateContext::new());
61
61
  let untracked_state = Arc::new(UntrackedStateContext::new());
62
- let commit_store = Arc::new(CommitStoreContext::new());
63
62
  let commit_graph = CommitGraphContext::new();
64
63
  let live_state = Arc::new(LiveStateContext::new(
65
64
  tracked_state.as_ref().clone(),
66
65
  *untracked_state,
67
66
  commit_graph,
68
67
  ));
69
- let version_ctx = Arc::new(VersionContext::new(Arc::clone(&untracked_state)));
68
+ let branch_ctx = Arc::new(BranchContext::new(Arc::clone(&untracked_state)));
70
69
  assert_initialized(storage.clone(), live_state.as_ref()).await?;
71
70
 
72
71
  // SessionContext::execute later projects these stable state contexts into one
@@ -75,144 +74,123 @@ impl Engine {
75
74
 
76
75
  Ok(Self {
77
76
  binary_cas: Arc::new(BinaryCasContext::new()),
78
- commit_store,
77
+ write_lock: storage.durable_write_lock(),
79
78
  storage,
80
79
  tracked_state,
81
80
  live_state,
82
- version_ctx,
81
+ branch_ctx,
83
82
  catalog_context: Arc::new(CatalogContext::new()),
84
83
  })
85
84
  }
86
85
 
87
- pub(crate) fn storage(&self) -> StorageContext {
86
+ pub(crate) fn storage(&self) -> StorageContext<B> {
88
87
  self.storage.clone()
89
88
  }
90
89
 
91
- /// Loads the current commit head for a version.
90
+ /// Loads the current commit head for a branch.
92
91
  ///
93
- /// This is the public engine-level form of the typed `version_ref` context:
94
- /// callers should not need to know that version heads are represented as
95
- /// untracked `lix_version_ref` rows in live_state.
96
- pub async fn load_version_head_commit_id(
92
+ /// This is the public engine-level form of the typed `branch_ref` context:
93
+ /// callers should not need to know that branch heads are represented as
94
+ /// untracked `lix_branch_ref` rows in live_state.
95
+ pub async fn load_branch_head_commit_id(
97
96
  &self,
98
- version_id: &str,
97
+ branch_id: &str,
99
98
  ) -> Result<Option<String>, LixError> {
100
- let mut transaction = self.storage.begin_read_transaction().await?;
99
+ let read = self.storage.begin_read(StorageReadOptions::default())?;
101
100
  let result = self
102
- .version_ctx
103
- .ref_reader(transaction.as_mut())
104
- .load_head_commit_id(version_id)
101
+ .branch_ctx
102
+ .ref_reader(&read)
103
+ .load_head_commit_id(branch_id)
105
104
  .await;
106
- match result {
107
- Ok(result) => {
108
- transaction.rollback().await?;
109
- Ok(result)
110
- }
111
- Err(error) => {
112
- let _ = transaction.rollback().await;
113
- Err(error)
114
- }
115
- }
105
+ result
116
106
  }
117
107
 
118
108
  pub async fn open_session(
119
109
  &self,
120
- active_version_id: impl Into<String>,
121
- ) -> Result<SessionContext, LixError> {
110
+ active_branch_id: impl Into<String>,
111
+ ) -> Result<SessionContext<B>, LixError> {
122
112
  SessionContext::open(
123
- active_version_id.into(),
113
+ active_branch_id.into(),
124
114
  self.storage(),
125
115
  Arc::clone(&self.live_state),
126
116
  Arc::clone(&self.tracked_state),
127
117
  Arc::clone(&self.binary_cas),
128
- Arc::clone(&self.commit_store),
129
- Arc::clone(&self.version_ctx),
118
+ Arc::clone(&self.branch_ctx),
130
119
  Arc::clone(&self.catalog_context),
120
+ self.write_lock.clone(),
131
121
  )
132
122
  .await
133
123
  }
134
124
 
135
- pub async fn open_workspace_session(&self) -> Result<SessionContext, LixError> {
125
+ pub async fn open_workspace_session(&self) -> Result<SessionContext<B>, LixError> {
136
126
  SessionContext::open_workspace(
137
127
  self.storage(),
138
128
  Arc::clone(&self.live_state),
139
129
  Arc::clone(&self.tracked_state),
140
130
  Arc::clone(&self.binary_cas),
141
- Arc::clone(&self.commit_store),
142
- Arc::clone(&self.version_ctx),
131
+ Arc::clone(&self.branch_ctx),
143
132
  Arc::clone(&self.catalog_context),
133
+ self.write_lock.clone(),
144
134
  )
145
135
  .await
146
136
  }
147
137
 
148
- /// Materializes the tracked serving projection root for one version from commit_store.
138
+ /// Rebuilds the tracked serving commit root for one branch from changelog.
149
139
  ///
150
140
  /// This is intentionally an engine-level operation: callers should not need
151
141
  /// to know which KV namespaces back changelog, commit graph, or tracked
152
- /// state. The current version head is read from the live-state facade so
153
- /// materialization uses the same moving-ref visibility as normal execution.
154
- pub async fn rebuild_tracked_state_for_version(
155
- &self,
156
- version_id: &str,
157
- ) -> Result<(), LixError> {
142
+ /// state. The current branch head is read from the live-state facade so
143
+ /// rebuild uses the same moving-ref visibility as normal execution.
144
+ pub async fn rebuild_tracked_state_for_branch(&self, branch_id: &str) -> Result<(), LixError> {
145
+ let _write_guard = self.write_lock.lock_owned().await;
158
146
  let head_commit_id = self
159
- .load_version_head_commit_id(version_id)
147
+ .load_branch_head_commit_id(branch_id)
160
148
  .await?
161
149
  .ok_or_else(|| {
162
- LixError::version_not_found(
163
- version_id.to_string(),
164
- "rebuild_tracked_state_for_version",
150
+ LixError::branch_not_found(
151
+ branch_id.to_string(),
152
+ "rebuild_tracked_state_for_branch",
165
153
  "target",
166
154
  )
167
155
  })?;
168
156
  let storage = self.storage();
169
- let mut transaction = storage.begin_write_transaction().await?;
157
+ let read = storage.begin_read(StorageReadOptions::default())?;
170
158
  let mut writes = StorageWriteSet::new();
171
- let materialize_result = self
159
+ let rebuild_result = self
172
160
  .tracked_state
173
- .materializer(
174
- transaction.as_mut(),
175
- &mut writes,
176
- self.commit_store.as_ref(),
177
- )
178
- .materialize_root_at(&head_commit_id)
161
+ .root_rebuilder(&read, &mut writes)
162
+ .rebuild_commit_root_at(&head_commit_id)
179
163
  .await;
180
- if let Err(error) = materialize_result {
181
- let _ = transaction.rollback().await;
182
- return Err(error);
183
- }
184
- if let Err(error) = writes.apply(&mut transaction.as_mut()).await {
185
- let _ = transaction.rollback().await;
164
+ if let Err(error) = rebuild_result {
186
165
  return Err(error);
187
166
  }
188
- transaction.commit().await
167
+ storage
168
+ .commit_write_set(writes, StorageWriteOptions::default())
169
+ .map(|_| ())
170
+ .map_err(Into::into)
189
171
  }
190
172
  }
191
173
 
192
- async fn assert_initialized(
193
- storage: StorageContext,
174
+ async fn assert_initialized<B>(
175
+ storage: StorageContext<B>,
194
176
  live_state: &LiveStateContext,
195
- ) -> Result<(), LixError> {
196
- let mut transaction = storage.begin_read_transaction().await?;
197
- let reader = live_state.reader(transaction.as_mut());
198
- let result = reader
177
+ ) -> Result<(), LixError>
178
+ where
179
+ B: StorageBackend + Clone + Send + Sync + 'static,
180
+ for<'backend> B::Read<'backend>: Clone + Send + Sync + 'static,
181
+ for<'backend> B::Write<'backend>: Send,
182
+ {
183
+ let read = storage.begin_read(StorageReadOptions::default())?;
184
+ let reader = live_state.reader(&read);
185
+ let initialized = reader
199
186
  .load_row(&LiveStateRowRequest {
200
187
  schema_key: "lix_key_value".to_string(),
201
- version_id: GLOBAL_VERSION_ID.to_string(),
202
- entity_id: EntityIdentity::single("lix_id"),
188
+ branch_id: GLOBAL_BRANCH_ID.to_string(),
189
+ entity_pk: EntityPk::single("lix_id"),
203
190
  file_id: NullableKeyFilter::Null,
204
191
  })
205
- .await;
206
- let initialized = match result {
207
- Ok(row) => {
208
- transaction.rollback().await?;
209
- row.is_some()
210
- }
211
- Err(error) => {
212
- let _ = transaction.rollback().await;
213
- return Err(error);
214
- }
215
- };
192
+ .await?
193
+ .is_some();
216
194
 
217
195
  if initialized {
218
196
  return Ok(());