@lix-js/sdk 0.6.0-preview.3 → 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 (235) hide show
  1. package/README.md +1 -1
  2. package/SKILL.md +105 -65
  3. package/dist/engine-wasm/index.js +4 -4
  4. package/dist/engine-wasm/wasm/lix_engine.d.ts +30 -6
  5. package/dist/engine-wasm/wasm/lix_engine.js +187 -117
  6. package/dist/engine-wasm/wasm/lix_engine.wasm +0 -0
  7. package/dist/engine-wasm/wasm/lix_engine.wasm.d.ts +14 -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 +42 -28
  11. package/dist/open-lix.js +49 -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 +819 -124
  94. package/dist-engine-src/src/session/create_branch.rs +94 -0
  95. package/dist-engine-src/src/session/execute.rs +260 -57
  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 +19 -16
  102. package/dist-engine-src/src/session/switch_branch.rs +113 -0
  103. package/dist-engine-src/src/session/transaction.rs +557 -0
  104. package/dist-engine-src/src/sql2/bind/classify.rs +102 -0
  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} +98 -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 +4 -5
  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 +30 -24
  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 -109
  218. package/dist-engine-src/src/sql2/classify.rs +0 -182
  219. package/dist-engine-src/src/sql2/entity_provider.rs +0 -3211
  220. package/dist-engine-src/src/sql2/execute.rs +0 -3440
  221. package/dist-engine-src/src/sql2/public_bind/assignment.rs +0 -46
  222. package/dist-engine-src/src/sql2/public_bind/capability.rs +0 -41
  223. package/dist-engine-src/src/sql2/public_bind/dml.rs +0 -166
  224. package/dist-engine-src/src/sql2/public_bind/mod.rs +0 -25
  225. package/dist-engine-src/src/sql2/public_bind/table.rs +0 -168
  226. package/dist-engine-src/src/sql2/version_scope.rs +0 -394
  227. package/dist-engine-src/src/storage/types.rs +0 -501
  228. package/dist-engine-src/src/tracked_state/by_file_index.rs +0 -98
  229. package/dist-engine-src/src/tracked_state/materializer.rs +0 -488
  230. package/dist-engine-src/src/transaction/live_state_overlay.rs +0 -35
  231. package/dist-engine-src/src/version/lifecycle.rs +0 -221
  232. package/dist-engine-src/src/version/mod.rs +0 -13
  233. package/dist-engine-src/src/version/refs.rs +0 -330
  234. package/dist-engine-src/src/version/stage_rows.rs +0 -67
  235. package/dist-engine-src/src/version/types.rs +0 -21
@@ -44,7 +44,7 @@ const FILESYSTEM_BINARY_BLOB_REF_SCHEMA_KEY: &str = "lix_binary_blob_ref";
44
44
  pub(crate) struct PluginInstallWriteContext {
45
45
  function_bindings: PreparedWriteFunctionBindings,
46
46
  public_surface_registry: SurfaceRegistry,
47
- target_version_id: String,
47
+ target_branch_id: String,
48
48
  active_account_ids: Vec<String>,
49
49
  origin_key: Option<String>,
50
50
  }
@@ -53,21 +53,21 @@ impl PluginInstallWriteContext {
53
53
  pub(crate) fn new(
54
54
  function_bindings: PreparedWriteFunctionBindings,
55
55
  public_surface_registry: SurfaceRegistry,
56
- target_version_id: impl Into<String>,
56
+ target_branch_id: impl Into<String>,
57
57
  active_account_ids: Vec<String>,
58
58
  origin_key: Option<String>,
59
59
  ) -> Self {
60
60
  Self {
61
61
  function_bindings,
62
62
  public_surface_registry,
63
- target_version_id: target_version_id.into(),
63
+ target_branch_id: target_branch_id.into(),
64
64
  active_account_ids,
65
65
  origin_key,
66
66
  }
67
67
  }
68
68
 
69
- fn target_version_id(&self) -> &str {
70
- &self.target_version_id
69
+ fn target_branch_id(&self) -> &str {
70
+ &self.target_branch_id
71
71
  }
72
72
  }
73
73
 
@@ -140,7 +140,7 @@ async fn install_plugin_with_writer(
140
140
 
141
141
  #[derive(Clone)]
142
142
  struct RegisteredSchemaRowSpec {
143
- entity_id: String,
143
+ entity_pk: String,
144
144
  registered_schema_key: String,
145
145
  snapshot: JsonValue,
146
146
  schema_json: JsonValue,
@@ -152,7 +152,7 @@ fn prepare_registered_schema_write_statement_from_schemas(
152
152
  ) -> Result<WriteCommand, LixError> {
153
153
  let target = require_resolved_surface(
154
154
  &context.public_surface_registry,
155
- "lix_registered_schema_by_version",
155
+ "lix_registered_schema_by_branch",
156
156
  )?;
157
157
  let schema_rows = schemas
158
158
  .iter()
@@ -160,18 +160,18 @@ fn prepare_registered_schema_write_statement_from_schemas(
160
160
  .collect::<Result<Vec<_>, _>>()?;
161
161
  let intended_post_state = schema_rows
162
162
  .iter()
163
- .map(|row| registered_schema_planned_row(row, context.target_version_id()))
163
+ .map(|row| registered_schema_planned_row(row, context.target_branch_id()))
164
164
  .collect::<Vec<_>>();
165
165
  let changes = schema_rows
166
166
  .iter()
167
167
  .map(|row| PublicChange {
168
- entity_id: row.entity_id.clone(),
168
+ entity_pk: row.entity_pk.clone(),
169
169
  schema_key: REGISTERED_SCHEMA_STORAGE_SCHEMA_KEY.to_string(),
170
170
  file_id: None,
171
171
  plugin_key: None,
172
172
  snapshot_content: Some(row.snapshot.to_string()),
173
173
  metadata: None,
174
- version_id: context.target_version_id().to_string(),
174
+ branch_id: context.target_branch_id().to_string(),
175
175
  origin_key: context.origin_key.clone(),
176
176
  })
177
177
  .collect::<Vec<_>>();
@@ -186,7 +186,7 @@ fn prepare_registered_schema_write_statement_from_schemas(
186
186
  prepare_public_tracked_write_statement(
187
187
  context,
188
188
  target,
189
- "lix_registered_schema_by_version",
189
+ "lix_registered_schema_by_branch",
190
190
  intended_post_state,
191
191
  PlannedFilesystemState::default(),
192
192
  changes,
@@ -211,7 +211,7 @@ fn prepare_plugin_archive_write_statement(
211
211
  plugin_directory_id: &str,
212
212
  context: &PluginInstallWriteContext,
213
213
  ) -> Result<WriteCommand, LixError> {
214
- let target = require_resolved_surface(&context.public_surface_registry, "lix_file_by_version")?;
214
+ let target = require_resolved_surface(&context.public_surface_registry, "lix_file_by_branch")?;
215
215
  let archive_id = plugin_storage_archive_file_id(parsed.manifest.key.as_str());
216
216
  let archive_path = plugin_storage_archive_path(parsed.manifest.key.as_str())?;
217
217
  let parsed_path = ParsedFilePath::try_from_path(&archive_path)?;
@@ -221,13 +221,13 @@ fn prepare_plugin_archive_write_statement(
221
221
  metadata: None,
222
222
  hidden: false,
223
223
  };
224
- let target_version_id = context.target_version_id();
224
+ let target_branch_id = context.target_branch_id();
225
225
  let filesystem_state = PlannedFilesystemState {
226
226
  files: [(
227
- (archive_id.clone(), target_version_id.to_string()),
227
+ (archive_id.clone(), target_branch_id.to_string()),
228
228
  PlannedFilesystemFile {
229
229
  file_id: archive_id.clone(),
230
- version_id: target_version_id.to_string(),
230
+ branch_id: target_branch_id.to_string(),
231
231
  untracked: false,
232
232
  descriptor: Some(descriptor.clone()),
233
233
  metadata_patch: OptionalTextPatch::Unchanged,
@@ -239,8 +239,8 @@ fn prepare_plugin_archive_write_statement(
239
239
  .collect(),
240
240
  };
241
241
  let intended_post_state = vec![
242
- plugin_archive_file_descriptor_row(&archive_id, target_version_id, &descriptor),
243
- plugin_archive_binary_blob_ref_row(&archive_id, target_version_id, archive_bytes)?,
242
+ plugin_archive_file_descriptor_row(&archive_id, target_branch_id, &descriptor),
243
+ plugin_archive_binary_blob_ref_row(&archive_id, target_branch_id, archive_bytes)?,
244
244
  ];
245
245
  let changes = intended_post_state
246
246
  .iter()
@@ -250,7 +250,7 @@ fn prepare_plugin_archive_write_statement(
250
250
  prepare_public_tracked_write_statement(
251
251
  context,
252
252
  target,
253
- "lix_file_by_version",
253
+ "lix_file_by_branch",
254
254
  intended_post_state,
255
255
  filesystem_state,
256
256
  changes,
@@ -266,7 +266,7 @@ fn registered_schema_row_spec_from_json(
266
266
  validate_lix_schema_definition(schema)?;
267
267
  let schema_key = schema_key_from_definition(schema)?;
268
268
  Ok(RegisteredSchemaRowSpec {
269
- entity_id: schema_key.entity_id(),
269
+ entity_pk: schema_key.entity_pk(),
270
270
  registered_schema_key: schema_key.schema_key,
271
271
  snapshot: json!({ "value": schema }),
272
272
  schema_json: schema.clone(),
@@ -275,10 +275,10 @@ fn registered_schema_row_spec_from_json(
275
275
 
276
276
  fn registered_schema_planned_row(
277
277
  row: &RegisteredSchemaRowSpec,
278
- target_version_id: &str,
278
+ target_branch_id: &str,
279
279
  ) -> PlannedStateRow {
280
280
  let mut values = BTreeMap::new();
281
- values.insert("entity_id".to_string(), Value::Text(row.entity_id.clone()));
281
+ values.insert("entity_pk".to_string(), Value::Text(row.entity_pk.clone()));
282
282
  values.insert(
283
283
  "schema_key".to_string(),
284
284
  Value::Text(REGISTERED_SCHEMA_STORAGE_SCHEMA_KEY.to_string()),
@@ -290,13 +290,13 @@ fn registered_schema_planned_row(
290
290
  Value::Json(row.snapshot.clone()),
291
291
  );
292
292
  values.insert(
293
- "version_id".to_string(),
294
- Value::Text(target_version_id.to_string()),
293
+ "branch_id".to_string(),
294
+ Value::Text(target_branch_id.to_string()),
295
295
  );
296
296
  PlannedStateRow {
297
- entity_id: row.entity_id.clone(),
297
+ entity_pk: row.entity_pk.clone(),
298
298
  schema_key: REGISTERED_SCHEMA_STORAGE_SCHEMA_KEY.to_string(),
299
- version_id: Some(target_version_id.to_string()),
299
+ branch_id: Some(target_branch_id.to_string()),
300
300
  values,
301
301
  origin_key: None,
302
302
  tombstone: false,
@@ -305,7 +305,7 @@ fn registered_schema_planned_row(
305
305
 
306
306
  fn plugin_archive_file_descriptor_row(
307
307
  archive_id: &str,
308
- target_version_id: &str,
308
+ target_branch_id: &str,
309
309
  descriptor: &PlannedFilesystemDescriptor,
310
310
  ) -> PlannedStateRow {
311
311
  let snapshot_content = json!({
@@ -316,7 +316,7 @@ fn plugin_archive_file_descriptor_row(
316
316
  })
317
317
  .to_string();
318
318
  let mut values = BTreeMap::new();
319
- values.insert("entity_id".to_string(), Value::Text(archive_id.to_string()));
319
+ values.insert("entity_pk".to_string(), Value::Text(archive_id.to_string()));
320
320
  values.insert(
321
321
  "schema_key".to_string(),
322
322
  Value::Text(FILESYSTEM_DESCRIPTOR_SCHEMA_KEY.to_string()),
@@ -328,13 +328,13 @@ fn plugin_archive_file_descriptor_row(
328
328
  Value::Text(snapshot_content),
329
329
  );
330
330
  values.insert(
331
- "version_id".to_string(),
332
- Value::Text(target_version_id.to_string()),
331
+ "branch_id".to_string(),
332
+ Value::Text(target_branch_id.to_string()),
333
333
  );
334
334
  PlannedStateRow {
335
- entity_id: archive_id.to_string(),
335
+ entity_pk: archive_id.to_string(),
336
336
  schema_key: FILESYSTEM_DESCRIPTOR_SCHEMA_KEY.to_string(),
337
- version_id: Some(target_version_id.to_string()),
337
+ branch_id: Some(target_branch_id.to_string()),
338
338
  values,
339
339
  origin_key: None,
340
340
  tombstone: false,
@@ -343,7 +343,7 @@ fn plugin_archive_file_descriptor_row(
343
343
 
344
344
  fn plugin_archive_binary_blob_ref_row(
345
345
  archive_id: &str,
346
- target_version_id: &str,
346
+ target_branch_id: &str,
347
347
  archive_bytes: &[u8],
348
348
  ) -> Result<PlannedStateRow, LixError> {
349
349
  let size_bytes = u64::try_from(archive_bytes.len()).map_err(|_| {
@@ -362,7 +362,7 @@ fn plugin_archive_binary_blob_ref_row(
362
362
  })
363
363
  .to_string();
364
364
  let mut values = BTreeMap::new();
365
- values.insert("entity_id".to_string(), Value::Text(archive_id.to_string()));
365
+ values.insert("entity_pk".to_string(), Value::Text(archive_id.to_string()));
366
366
  values.insert(
367
367
  "schema_key".to_string(),
368
368
  Value::Text(FILESYSTEM_BINARY_BLOB_REF_SCHEMA_KEY.to_string()),
@@ -374,13 +374,13 @@ fn plugin_archive_binary_blob_ref_row(
374
374
  Value::Text(snapshot_content),
375
375
  );
376
376
  values.insert(
377
- "version_id".to_string(),
378
- Value::Text(target_version_id.to_string()),
377
+ "branch_id".to_string(),
378
+ Value::Text(target_branch_id.to_string()),
379
379
  );
380
380
  Ok(PlannedStateRow {
381
- entity_id: archive_id.to_string(),
381
+ entity_pk: archive_id.to_string(),
382
382
  schema_key: FILESYSTEM_BINARY_BLOB_REF_SCHEMA_KEY.to_string(),
383
- version_id: Some(target_version_id.to_string()),
383
+ branch_id: Some(target_branch_id.to_string()),
384
384
  values,
385
385
  origin_key: None,
386
386
  tombstone: false,
@@ -414,7 +414,7 @@ fn prepare_public_tracked_write_statement(
414
414
  operation_kind: PreparedWriteOperationKind::Insert,
415
415
  target,
416
416
  on_conflict_action: None,
417
- requested_version_id: Some(context.target_version_id().to_string()),
417
+ requested_branch_id: Some(context.target_branch_id().to_string()),
418
418
  active_account_ids: context.active_account_ids.clone(),
419
419
  origin_key: context.origin_key.clone(),
420
420
  resolved_write_plan: Some(PreparedResolvedWritePlan {
@@ -480,7 +480,7 @@ fn semantic_effect_markers_from_changes(changes: &[PublicChange]) -> Vec<Semanti
480
480
  effect_key: "state.upsert".to_string(),
481
481
  target: format!(
482
482
  "{}:{}@{}",
483
- change.schema_key, change.entity_id, change.version_id
483
+ change.schema_key, change.entity_pk, change.branch_id
484
484
  ),
485
485
  })
486
486
  .collect()
@@ -488,7 +488,7 @@ fn semantic_effect_markers_from_changes(changes: &[PublicChange]) -> Vec<Semanti
488
488
 
489
489
  fn planned_row_to_public_change(row: &PlannedStateRow) -> Result<PublicChange, LixError> {
490
490
  Ok(PublicChange {
491
- entity_id: row.entity_id.clone(),
491
+ entity_pk: row.entity_pk.clone(),
492
492
  schema_key: row.schema_key.clone(),
493
493
  file_id: planned_row_text_value(row, "file_id"),
494
494
  plugin_key: planned_row_text_value(row, "plugin_key"),
@@ -498,14 +498,14 @@ fn planned_row_to_public_change(row: &PlannedStateRow) -> Result<PublicChange, L
498
498
  planned_row_json_text_value(row, "snapshot_content")
499
499
  },
500
500
  metadata: planned_row_json_text_value(row, "metadata"),
501
- version_id: row
502
- .version_id
501
+ branch_id: row
502
+ .branch_id
503
503
  .clone()
504
- .or_else(|| planned_row_text_value(row, "version_id"))
504
+ .or_else(|| planned_row_text_value(row, "branch_id"))
505
505
  .ok_or_else(|| {
506
506
  LixError::new(
507
507
  "LIX_ERROR_UNKNOWN",
508
- "semantic tracked write requires a concrete version_id",
508
+ "semantic tracked write requires a concrete branch_id",
509
509
  )
510
510
  })?,
511
511
  origin_key: row.origin_key.clone(),
@@ -550,11 +550,11 @@ fn semantic_idempotency_key(
550
550
 
551
551
  fn summarize_change(change: &PublicChange) -> JsonValue {
552
552
  json!({
553
- "entity_id": change.entity_id,
553
+ "entity_pk": change.entity_pk,
554
554
  "schema_key": change.schema_key,
555
555
  "file_id": change.file_id,
556
556
  "plugin_key": change.plugin_key,
557
- "version_id": change.version_id,
557
+ "branch_id": change.branch_id,
558
558
  "origin_key": change.origin_key,
559
559
  "snapshot_content": change.snapshot_content.as_ref().map(|snapshot| {
560
560
  stable_content_fingerprint_hex(snapshot.as_bytes())
@@ -564,9 +564,9 @@ fn summarize_change(change: &PublicChange) -> JsonValue {
564
564
 
565
565
  fn summarize_planned_row(row: &PlannedStateRow) -> JsonValue {
566
566
  json!({
567
- "entity_id": row.entity_id,
567
+ "entity_pk": row.entity_pk,
568
568
  "schema_key": row.schema_key,
569
- "version_id": row.version_id,
569
+ "branch_id": row.branch_id,
570
570
  "tombstone": row.tombstone,
571
571
  "values": row
572
572
  .values
@@ -100,13 +100,13 @@ impl DetectStateContextConfig {
100
100
  #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
101
101
  #[serde(rename_all = "snake_case")]
102
102
  pub enum StateContextColumn {
103
- EntityId,
103
+ EntityPk,
104
104
  SchemaKey,
105
105
  SchemaVersion,
106
106
  SnapshotContent,
107
107
  FileId,
108
108
  PluginKey,
109
- VersionId,
109
+ BranchId,
110
110
  ChangeId,
111
111
  Metadata,
112
112
  CreatedAt,
@@ -117,7 +117,7 @@ pub enum StateContextColumn {
117
117
  impl StateContextColumn {
118
118
  pub const fn default_active_state_columns() -> &'static [StateContextColumn] {
119
119
  &[
120
- StateContextColumn::EntityId,
120
+ StateContextColumn::EntityPk,
121
121
  StateContextColumn::SchemaKey,
122
122
  StateContextColumn::SchemaVersion,
123
123
  StateContextColumn::SnapshotContent,
@@ -357,7 +357,7 @@ mod tests {
357
357
  let config = DetectStateContextConfig {
358
358
  include_active_state: Some(true),
359
359
  columns: Some(vec![
360
- StateContextColumn::EntityId,
360
+ StateContextColumn::EntityPk,
361
361
  StateContextColumn::SchemaKey,
362
362
  ]),
363
363
  };
@@ -365,7 +365,7 @@ mod tests {
365
365
  assert_eq!(
366
366
  config.resolved_columns_or_default(),
367
367
  Some(vec![
368
- StateContextColumn::EntityId,
368
+ StateContextColumn::EntityPk,
369
369
  StateContextColumn::SchemaKey
370
370
  ])
371
371
  );
@@ -457,7 +457,7 @@ mod tests {
457
457
  "detect_changes": {
458
458
  "state_context": {
459
459
  "include_active_state": true,
460
- "columns": ["entity_id", "schema_key", "snapshot_content"]
460
+ "columns": ["entity_pk", "schema_key", "snapshot_content"]
461
461
  }
462
462
  }
463
463
  }"#,
@@ -475,7 +475,7 @@ mod tests {
475
475
  assert_eq!(
476
476
  state_context.columns,
477
477
  Some(vec![
478
- StateContextColumn::EntityId,
478
+ StateContextColumn::EntityPk,
479
479
  StateContextColumn::SchemaKey,
480
480
  StateContextColumn::SnapshotContent
481
481
  ])
@@ -200,278 +200,3 @@ where
200
200
  apply_changes_with_plugin(self, plugin, payload).await
201
201
  }
202
202
  }
203
-
204
- #[cfg(test)]
205
- mod tests {
206
- use super::*;
207
- use crate::binary_cas::codec::{
208
- binary_blob_hash_bytes, encode_binary_cas_chunk, encode_binary_cas_manifest,
209
- encode_binary_cas_manifest_chunk, BinaryCasManifest, BinaryChunkCodec,
210
- };
211
- use crate::binary_cas::kv::{
212
- BINARY_CAS_CHUNK_NAMESPACE, BINARY_CAS_MANIFEST_CHUNK_NAMESPACE,
213
- BINARY_CAS_MANIFEST_NAMESPACE,
214
- };
215
- use crate::{
216
- BackendKvEntryPage, BackendKvExistsBatch, BackendKvExistsGroup,
217
- BackendKvGetRequest, BackendKvKeyPage, BackendKvScanRange, BackendKvScanRequest,
218
- BackendKvValueBatch, BackendKvValueGroup, BackendKvValuePage, BackendKvWriteBatch,
219
- BackendKvWriteStats, BackendReadTransaction, BackendWriteTransaction, BytePageBuilder,
220
- };
221
- use async_trait::async_trait;
222
- use std::io::{Cursor, Write};
223
- use zip::write::SimpleFileOptions;
224
- use zip::{CompressionMethod, ZipWriter};
225
-
226
- struct InstalledPluginLookupBackend {
227
- archive_bytes: Vec<u8>,
228
- }
229
-
230
- struct PluginLookupTransaction {
231
- archive_bytes: Vec<u8>,
232
- }
233
-
234
- #[async_trait]
235
- impl Backend for InstalledPluginLookupBackend {
236
- async fn begin_read_transaction(
237
- &self,
238
- ) -> Result<Box<dyn BackendReadTransaction + Send + Sync + 'static>, LixError> {
239
- Ok(Box::new(PluginLookupTransaction {
240
- archive_bytes: self.archive_bytes.clone(),
241
- }))
242
- }
243
-
244
- async fn begin_write_transaction(
245
- &self,
246
- ) -> Result<Box<dyn BackendWriteTransaction + Send + Sync + 'static>, LixError> {
247
- Ok(Box::new(PluginLookupTransaction {
248
- archive_bytes: self.archive_bytes.clone(),
249
- }))
250
- }
251
- }
252
-
253
- #[async_trait]
254
- impl BackendReadTransaction for PluginLookupTransaction {
255
- async fn get_values(
256
- &mut self,
257
- request: BackendKvGetRequest,
258
- ) -> Result<BackendKvValueBatch, LixError> {
259
- let mut groups = Vec::with_capacity(request.groups.len());
260
- for group in request.groups {
261
- let namespace = group.namespace.clone();
262
- let mut values = BytePageBuilder::with_capacity(group.keys.len(), 0);
263
- let mut present = Vec::with_capacity(group.keys.len());
264
- for key in group.keys {
265
- if let Some(value) = test_kv_get(&self.archive_bytes, &group.namespace, &key)? {
266
- values.push(value);
267
- present.push(true);
268
- } else {
269
- values.push([]);
270
- present.push(false);
271
- }
272
- }
273
- groups.push(BackendKvValueGroup::new(namespace, values.finish(), present));
274
- }
275
- Ok(BackendKvValueBatch { groups })
276
- }
277
-
278
- async fn exists_many(
279
- &mut self,
280
- request: BackendKvGetRequest,
281
- ) -> Result<BackendKvExistsBatch, LixError> {
282
- let mut groups = Vec::with_capacity(request.groups.len());
283
- for group in request.groups {
284
- let namespace = group.namespace.clone();
285
- let exists = group
286
- .keys
287
- .iter()
288
- .map(|key| test_kv_get(&self.archive_bytes, &group.namespace, key))
289
- .collect::<Result<Vec<_>, LixError>>()?
290
- .into_iter()
291
- .map(|value| value.is_some())
292
- .collect();
293
- groups.push(BackendKvExistsGroup {
294
- namespace,
295
- exists,
296
- });
297
- }
298
- Ok(BackendKvExistsBatch { groups })
299
- }
300
-
301
- async fn scan_keys(
302
- &mut self,
303
- request: BackendKvScanRequest,
304
- ) -> Result<BackendKvKeyPage, LixError> {
305
- let entries = test_kv_scan(&self.archive_bytes, request)?;
306
- Ok(BackendKvKeyPage {
307
- keys: entries.keys,
308
- resume_after: entries.resume_after,
309
- })
310
- }
311
-
312
- async fn scan_values(
313
- &mut self,
314
- request: BackendKvScanRequest,
315
- ) -> Result<BackendKvValuePage, LixError> {
316
- let entries = test_kv_scan(&self.archive_bytes, request)?;
317
- Ok(BackendKvValuePage {
318
- values: entries.values,
319
- resume_after: entries.resume_after,
320
- })
321
- }
322
-
323
- async fn scan_entries(
324
- &mut self,
325
- request: BackendKvScanRequest,
326
- ) -> Result<BackendKvEntryPage, LixError> {
327
- test_kv_scan(&self.archive_bytes, request)
328
- }
329
-
330
- async fn rollback(self: Box<Self>) -> Result<(), LixError> {
331
- Ok(())
332
- }
333
- }
334
-
335
- #[async_trait]
336
- impl BackendWriteTransaction for PluginLookupTransaction {
337
- async fn write_kv_batch(&mut self, _batch: BackendKvWriteBatch) -> Result<BackendKvWriteStats, LixError> {
338
- Err(LixError::new(
339
- "LIX_ERROR_UNKNOWN",
340
- "plugin lookup test backend is read-only",
341
- ))
342
- }
343
-
344
- async fn commit(self: Box<Self>) -> Result<(), LixError> {
345
- Ok(())
346
- }
347
- }
348
-
349
- fn test_kv_get(
350
- archive_bytes: &[u8],
351
- namespace: &str,
352
- key: &[u8],
353
- ) -> Result<Option<Vec<u8>>, LixError> {
354
- match (namespace, key) {
355
- (BINARY_CAS_MANIFEST_NAMESPACE, key)
356
- if key == binary_blob_hash_bytes(archive_bytes).as_slice() =>
357
- {
358
- Ok(Some(encode_binary_cas_manifest(
359
- &BinaryCasManifest::Chunked {
360
- size_bytes: archive_bytes.len() as u64,
361
- chunk_count: 1,
362
- },
363
- )))
364
- }
365
- (BINARY_CAS_CHUNK_NAMESPACE, key)
366
- if key == binary_blob_hash_bytes(archive_bytes).as_slice() =>
367
- {
368
- Ok(Some(encode_binary_cas_chunk(
369
- BinaryChunkCodec::Raw,
370
- archive_bytes.len() as u64,
371
- archive_bytes,
372
- )))
373
- }
374
- _ => Ok(None),
375
- }
376
- }
377
-
378
- fn test_kv_scan(
379
- archive_bytes: &[u8],
380
- request: BackendKvScanRequest,
381
- ) -> Result<BackendKvEntryPage, LixError> {
382
- if request.namespace != BINARY_CAS_MANIFEST_CHUNK_NAMESPACE {
383
- return Ok(BackendKvEntryPage {
384
- keys: BytePageBuilder::new().finish(),
385
- values: BytePageBuilder::new().finish(),
386
- resume_after: None,
387
- });
388
- }
389
- let blob_hash = binary_blob_hash_bytes(archive_bytes);
390
- let chunk_hash = binary_blob_hash_bytes(archive_bytes);
391
- let mut key = blob_hash.to_vec();
392
- key.extend_from_slice(&0u64.to_be_bytes());
393
- let include = match request.range {
394
- BackendKvScanRange::Prefix(prefix) => key.starts_with(&prefix),
395
- BackendKvScanRange::Range { start, end } => key >= start && key < end,
396
- };
397
- if !include || request.after.as_deref().is_some_and(|after| key.as_slice() <= after) {
398
- return Ok(BackendKvEntryPage {
399
- keys: BytePageBuilder::new().finish(),
400
- values: BytePageBuilder::new().finish(),
401
- resume_after: None,
402
- });
403
- }
404
- let value = encode_binary_cas_manifest_chunk(&chunk_hash, archive_bytes.len() as u64);
405
- let mut keys = BytePageBuilder::with_capacity(1, key.len());
406
- let mut values = BytePageBuilder::with_capacity(1, value.len());
407
- let mut resume_after = None;
408
- if request.limit > 0 {
409
- resume_after = Some(key.clone());
410
- keys.push(&key);
411
- values.push(&value);
412
- }
413
- let resume_after = (request.limit == 0).then_some(resume_after).flatten();
414
- Ok(BackendKvEntryPage {
415
- keys: keys.finish(),
416
- values: values.finish(),
417
- resume_after,
418
- })
419
- }
420
-
421
- fn build_archive(entries: &[(&str, &[u8])]) -> Vec<u8> {
422
- let options = SimpleFileOptions::default().compression_method(CompressionMethod::Stored);
423
- let cursor = Cursor::new(Vec::new());
424
- let mut writer = ZipWriter::new(cursor);
425
- for (path, bytes) in entries {
426
- writer
427
- .start_file(*path, options)
428
- .expect("archive entry start should succeed");
429
- writer
430
- .write_all(bytes)
431
- .expect("archive entry write should succeed");
432
- }
433
- writer
434
- .finish()
435
- .expect("archive finish should succeed")
436
- .into_inner()
437
- }
438
-
439
- fn build_plugin_archive(manifest_json: &str) -> Vec<u8> {
440
- let wasm = [0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00];
441
- build_archive(&[
442
- ("manifest.json", manifest_json.as_bytes()),
443
- ("plugin.wasm", &wasm),
444
- ])
445
- }
446
-
447
- fn plugin_manifest_json(key: &str) -> String {
448
- format!(
449
- r#"{{
450
- "key":"{key}",
451
- "runtime":"wasm-component-v1",
452
- "api_version":"0.1.0",
453
- "match":{{"path_glob":"*.json"}},
454
- "entry":"plugin.wasm",
455
- "schemas":["schema/plugin_json_schema.json"]
456
- }}"#
457
- )
458
- }
459
-
460
- #[tokio::test]
461
- async fn installed_plugin_manifest_key_exists_reads_installed_manifest_keys() {
462
- let backend = InstalledPluginLookupBackend {
463
- archive_bytes: build_plugin_archive(&plugin_manifest_json("plugin_json")),
464
- };
465
-
466
- assert!(
467
- installed_plugin_manifest_key_exists(&backend, "plugin_json")
468
- .await
469
- .expect("installed manifest key lookup should succeed")
470
- );
471
- assert!(
472
- !installed_plugin_manifest_key_exists(&backend, "missing_plugin")
473
- .await
474
- .expect("missing manifest key lookup should succeed")
475
- );
476
- }
477
- }
@@ -60,12 +60,13 @@
60
60
  "items": {
61
61
  "type": "string",
62
62
  "enum": [
63
- "entity_id",
63
+ "entity_pk",
64
64
  "schema_key",
65
+ "schema_version",
65
66
  "snapshot_content",
66
67
  "file_id",
67
68
  "plugin_key",
68
- "version_id",
69
+ "branch_id",
69
70
  "change_id",
70
71
  "metadata",
71
72
  "created_at",
@@ -73,7 +74,7 @@
73
74
  ]
74
75
  },
75
76
  "contains": {
76
- "const": "entity_id"
77
+ "const": "entity_pk"
77
78
  }
78
79
  }
79
80
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "x-lix-key": "lix_binary_blob_ref",
3
- "description": "Metadata pointer from a file version to its binary payload in internal CAS storage.",
3
+ "description": "Metadata pointer from a file row to its binary payload in internal CAS storage.",
4
4
  "x-lix-primary-key": [
5
5
  "/id"
6
6
  ],
@@ -8,7 +8,7 @@
8
8
  "properties": {
9
9
  "id": {
10
10
  "type": "string",
11
- "description": "File/entity identifier (matches lix_file.id) for this binary reference row."
11
+ "description": "File primary-key value (matches lix_file.id) for this binary reference row."
12
12
  },
13
13
  "blob_hash": {
14
14
  "type": "string",