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

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 (223) hide show
  1. package/README.md +76 -4
  2. package/dist/errors.d.ts +7 -0
  3. package/dist/errors.js +19 -0
  4. package/dist/index.d.ts +4 -5
  5. package/dist/index.js +3 -3
  6. package/dist/native.d.ts +1 -0
  7. package/dist/native.js +47 -0
  8. package/dist/open-lix.d.ts +39 -201
  9. package/dist/open-lix.js +59 -284
  10. package/dist/result.d.ts +18 -0
  11. package/dist/result.js +48 -0
  12. package/dist/types.d.ts +114 -1
  13. package/dist/value.d.ts +28 -0
  14. package/dist/value.js +245 -0
  15. package/package.json +20 -50
  16. package/SKILL.md +0 -506
  17. package/dist/builtin-schemas.d.ts +0 -1
  18. package/dist/builtin-schemas.js +0 -1
  19. package/dist/engine-wasm/index.d.ts +0 -87
  20. package/dist/engine-wasm/index.js +0 -339
  21. package/dist/engine-wasm/wasm/lix_engine.d.ts +0 -79
  22. package/dist/engine-wasm/wasm/lix_engine.js +0 -821
  23. package/dist/engine-wasm/wasm/lix_engine.wasm +0 -0
  24. package/dist/engine-wasm/wasm/lix_engine.wasm.d.ts +0 -26
  25. package/dist/generated/builtin-schemas.d.ts +0 -427
  26. package/dist/generated/builtin-schemas.js +0 -643
  27. package/dist/sqlite/index.d.ts +0 -12
  28. package/dist/sqlite/index.js +0 -303
  29. package/dist-engine-src/README.md +0 -18
  30. package/dist-engine-src/src/backend/kv.rs +0 -358
  31. package/dist-engine-src/src/backend/mod.rs +0 -12
  32. package/dist-engine-src/src/backend/testing.rs +0 -658
  33. package/dist-engine-src/src/backend/types.rs +0 -96
  34. package/dist-engine-src/src/binary_cas/chunking.rs +0 -31
  35. package/dist-engine-src/src/binary_cas/codec.rs +0 -346
  36. package/dist-engine-src/src/binary_cas/context.rs +0 -139
  37. package/dist-engine-src/src/binary_cas/kv.rs +0 -1063
  38. package/dist-engine-src/src/binary_cas/mod.rs +0 -11
  39. package/dist-engine-src/src/binary_cas/types.rs +0 -121
  40. package/dist-engine-src/src/catalog/context.rs +0 -412
  41. package/dist-engine-src/src/catalog/mod.rs +0 -10
  42. package/dist-engine-src/src/catalog/schema.rs +0 -4
  43. package/dist-engine-src/src/catalog/snapshot.rs +0 -1114
  44. package/dist-engine-src/src/cel/context.rs +0 -86
  45. package/dist-engine-src/src/cel/error.rs +0 -19
  46. package/dist-engine-src/src/cel/mod.rs +0 -8
  47. package/dist-engine-src/src/cel/provider.rs +0 -9
  48. package/dist-engine-src/src/cel/runtime.rs +0 -167
  49. package/dist-engine-src/src/cel/value.rs +0 -50
  50. package/dist-engine-src/src/commit_graph/context.rs +0 -901
  51. package/dist-engine-src/src/commit_graph/mod.rs +0 -11
  52. package/dist-engine-src/src/commit_graph/types.rs +0 -109
  53. package/dist-engine-src/src/commit_graph/walker.rs +0 -756
  54. package/dist-engine-src/src/commit_store/codec.rs +0 -887
  55. package/dist-engine-src/src/commit_store/context.rs +0 -944
  56. package/dist-engine-src/src/commit_store/materialization.rs +0 -84
  57. package/dist-engine-src/src/commit_store/mod.rs +0 -16
  58. package/dist-engine-src/src/commit_store/storage.rs +0 -600
  59. package/dist-engine-src/src/commit_store/types.rs +0 -215
  60. package/dist-engine-src/src/common/error.rs +0 -313
  61. package/dist-engine-src/src/common/fingerprint.rs +0 -3
  62. package/dist-engine-src/src/common/fs_path.rs +0 -1336
  63. package/dist-engine-src/src/common/identity.rs +0 -145
  64. package/dist-engine-src/src/common/json_pointer.rs +0 -67
  65. package/dist-engine-src/src/common/metadata.rs +0 -40
  66. package/dist-engine-src/src/common/mod.rs +0 -23
  67. package/dist-engine-src/src/common/types.rs +0 -105
  68. package/dist-engine-src/src/common/wire.rs +0 -222
  69. package/dist-engine-src/src/domain.rs +0 -324
  70. package/dist-engine-src/src/engine.rs +0 -225
  71. package/dist-engine-src/src/entity_identity.rs +0 -405
  72. package/dist-engine-src/src/functions/context.rs +0 -292
  73. package/dist-engine-src/src/functions/deterministic.rs +0 -113
  74. package/dist-engine-src/src/functions/mod.rs +0 -18
  75. package/dist-engine-src/src/functions/provider.rs +0 -130
  76. package/dist-engine-src/src/functions/state.rs +0 -336
  77. package/dist-engine-src/src/functions/types.rs +0 -37
  78. package/dist-engine-src/src/init.rs +0 -558
  79. package/dist-engine-src/src/json_store/compression.rs +0 -77
  80. package/dist-engine-src/src/json_store/context.rs +0 -423
  81. package/dist-engine-src/src/json_store/encoded.rs +0 -15
  82. package/dist-engine-src/src/json_store/mod.rs +0 -12
  83. package/dist-engine-src/src/json_store/store.rs +0 -1109
  84. package/dist-engine-src/src/json_store/types.rs +0 -217
  85. package/dist-engine-src/src/lib.rs +0 -62
  86. package/dist-engine-src/src/live_state/context.rs +0 -2019
  87. package/dist-engine-src/src/live_state/mod.rs +0 -15
  88. package/dist-engine-src/src/live_state/overlay.rs +0 -75
  89. package/dist-engine-src/src/live_state/reader.rs +0 -23
  90. package/dist-engine-src/src/live_state/types.rs +0 -222
  91. package/dist-engine-src/src/live_state/visibility.rs +0 -223
  92. package/dist-engine-src/src/plugin/archive.rs +0 -438
  93. package/dist-engine-src/src/plugin/component.rs +0 -183
  94. package/dist-engine-src/src/plugin/install.rs +0 -619
  95. package/dist-engine-src/src/plugin/manifest.rs +0 -516
  96. package/dist-engine-src/src/plugin/materializer.rs +0 -477
  97. package/dist-engine-src/src/plugin/mod.rs +0 -33
  98. package/dist-engine-src/src/plugin/plugin_manifest.json +0 -118
  99. package/dist-engine-src/src/plugin/storage.rs +0 -74
  100. package/dist-engine-src/src/schema/annotations/defaults.rs +0 -275
  101. package/dist-engine-src/src/schema/annotations/mod.rs +0 -1
  102. package/dist-engine-src/src/schema/builtin/lix_account.json +0 -21
  103. package/dist-engine-src/src/schema/builtin/lix_active_account.json +0 -29
  104. package/dist-engine-src/src/schema/builtin/lix_binary_blob_ref.json +0 -29
  105. package/dist-engine-src/src/schema/builtin/lix_change.json +0 -63
  106. package/dist-engine-src/src/schema/builtin/lix_change_author.json +0 -45
  107. package/dist-engine-src/src/schema/builtin/lix_commit.json +0 -24
  108. package/dist-engine-src/src/schema/builtin/lix_commit_edge.json +0 -53
  109. package/dist-engine-src/src/schema/builtin/lix_directory_descriptor.json +0 -52
  110. package/dist-engine-src/src/schema/builtin/lix_file_descriptor.json +0 -52
  111. package/dist-engine-src/src/schema/builtin/lix_key_value.json +0 -40
  112. package/dist-engine-src/src/schema/builtin/lix_label.json +0 -29
  113. package/dist-engine-src/src/schema/builtin/lix_label_assignment.json +0 -74
  114. package/dist-engine-src/src/schema/builtin/lix_registered_schema.json +0 -25
  115. package/dist-engine-src/src/schema/builtin/lix_version_descriptor.json +0 -34
  116. package/dist-engine-src/src/schema/builtin/lix_version_ref.json +0 -48
  117. package/dist-engine-src/src/schema/builtin/mod.rs +0 -222
  118. package/dist-engine-src/src/schema/compatibility.rs +0 -787
  119. package/dist-engine-src/src/schema/definition.json +0 -187
  120. package/dist-engine-src/src/schema/definition.rs +0 -742
  121. package/dist-engine-src/src/schema/key.rs +0 -138
  122. package/dist-engine-src/src/schema/mod.rs +0 -20
  123. package/dist-engine-src/src/schema/seed.rs +0 -14
  124. package/dist-engine-src/src/schema/tests.rs +0 -780
  125. package/dist-engine-src/src/session/context.rs +0 -404
  126. package/dist-engine-src/src/session/create_version.rs +0 -88
  127. package/dist-engine-src/src/session/execute.rs +0 -541
  128. package/dist-engine-src/src/session/merge/analysis.rs +0 -102
  129. package/dist-engine-src/src/session/merge/apply.rs +0 -23
  130. package/dist-engine-src/src/session/merge/conflicts.rs +0 -63
  131. package/dist-engine-src/src/session/merge/mod.rs +0 -11
  132. package/dist-engine-src/src/session/merge/stats.rs +0 -65
  133. package/dist-engine-src/src/session/merge/version.rs +0 -427
  134. package/dist-engine-src/src/session/mod.rs +0 -27
  135. package/dist-engine-src/src/session/optimization9_sql2_bench.rs +0 -100
  136. package/dist-engine-src/src/session/switch_version.rs +0 -110
  137. package/dist-engine-src/src/session/transaction.rs +0 -76
  138. package/dist-engine-src/src/sql2/change_provider.rs +0 -331
  139. package/dist-engine-src/src/sql2/classify.rs +0 -174
  140. package/dist-engine-src/src/sql2/context.rs +0 -311
  141. package/dist-engine-src/src/sql2/directory_history_provider.rs +0 -631
  142. package/dist-engine-src/src/sql2/directory_provider.rs +0 -2453
  143. package/dist-engine-src/src/sql2/dml.rs +0 -148
  144. package/dist-engine-src/src/sql2/entity_history_provider.rs +0 -440
  145. package/dist-engine-src/src/sql2/entity_provider.rs +0 -3211
  146. package/dist-engine-src/src/sql2/error.rs +0 -215
  147. package/dist-engine-src/src/sql2/execute.rs +0 -3533
  148. package/dist-engine-src/src/sql2/file_history_provider.rs +0 -910
  149. package/dist-engine-src/src/sql2/file_provider.rs +0 -3679
  150. package/dist-engine-src/src/sql2/filesystem_planner.rs +0 -1490
  151. package/dist-engine-src/src/sql2/filesystem_predicates.rs +0 -159
  152. package/dist-engine-src/src/sql2/filesystem_visibility.rs +0 -383
  153. package/dist-engine-src/src/sql2/history_projection.rs +0 -56
  154. package/dist-engine-src/src/sql2/history_provider.rs +0 -412
  155. package/dist-engine-src/src/sql2/history_route.rs +0 -657
  156. package/dist-engine-src/src/sql2/lix_state_provider.rs +0 -2512
  157. package/dist-engine-src/src/sql2/mod.rs +0 -47
  158. package/dist-engine-src/src/sql2/predicate_typecheck.rs +0 -246
  159. package/dist-engine-src/src/sql2/public_bind/assignment.rs +0 -46
  160. package/dist-engine-src/src/sql2/public_bind/capability.rs +0 -41
  161. package/dist-engine-src/src/sql2/public_bind/dml.rs +0 -172
  162. package/dist-engine-src/src/sql2/public_bind/mod.rs +0 -26
  163. package/dist-engine-src/src/sql2/public_bind/table.rs +0 -168
  164. package/dist-engine-src/src/sql2/read_only.rs +0 -63
  165. package/dist-engine-src/src/sql2/record_batch.rs +0 -17
  166. package/dist-engine-src/src/sql2/result_metadata.rs +0 -29
  167. package/dist-engine-src/src/sql2/runtime.rs +0 -60
  168. package/dist-engine-src/src/sql2/session.rs +0 -132
  169. package/dist-engine-src/src/sql2/udfs/common.rs +0 -295
  170. package/dist-engine-src/src/sql2/udfs/lix_active_version_commit_id.rs +0 -53
  171. package/dist-engine-src/src/sql2/udfs/lix_empty_blob.rs +0 -47
  172. package/dist-engine-src/src/sql2/udfs/lix_json.rs +0 -100
  173. package/dist-engine-src/src/sql2/udfs/lix_json_get.rs +0 -99
  174. package/dist-engine-src/src/sql2/udfs/lix_json_get_text.rs +0 -99
  175. package/dist-engine-src/src/sql2/udfs/lix_text_decode.rs +0 -82
  176. package/dist-engine-src/src/sql2/udfs/lix_text_encode.rs +0 -85
  177. package/dist-engine-src/src/sql2/udfs/lix_timestamp.rs +0 -76
  178. package/dist-engine-src/src/sql2/udfs/lix_uuid_v7.rs +0 -76
  179. package/dist-engine-src/src/sql2/udfs/mod.rs +0 -89
  180. package/dist-engine-src/src/sql2/udfs/public_call.rs +0 -238
  181. package/dist-engine-src/src/sql2/version_provider.rs +0 -1202
  182. package/dist-engine-src/src/sql2/version_scope.rs +0 -394
  183. package/dist-engine-src/src/sql2/write_normalization.rs +0 -345
  184. package/dist-engine-src/src/storage/context.rs +0 -356
  185. package/dist-engine-src/src/storage/mod.rs +0 -14
  186. package/dist-engine-src/src/storage/read_scope.rs +0 -88
  187. package/dist-engine-src/src/storage/types.rs +0 -501
  188. package/dist-engine-src/src/storage_bench.rs +0 -4863
  189. package/dist-engine-src/src/test_support.rs +0 -228
  190. package/dist-engine-src/src/tracked_state/by_file_index.rs +0 -98
  191. package/dist-engine-src/src/tracked_state/codec.rs +0 -2085
  192. package/dist-engine-src/src/tracked_state/context.rs +0 -1867
  193. package/dist-engine-src/src/tracked_state/diff.rs +0 -686
  194. package/dist-engine-src/src/tracked_state/materialization.rs +0 -403
  195. package/dist-engine-src/src/tracked_state/materializer.rs +0 -488
  196. package/dist-engine-src/src/tracked_state/merge.rs +0 -492
  197. package/dist-engine-src/src/tracked_state/mod.rs +0 -32
  198. package/dist-engine-src/src/tracked_state/storage.rs +0 -375
  199. package/dist-engine-src/src/tracked_state/tree.rs +0 -3187
  200. package/dist-engine-src/src/tracked_state/types.rs +0 -231
  201. package/dist-engine-src/src/transaction/commit.rs +0 -1484
  202. package/dist-engine-src/src/transaction/context.rs +0 -1548
  203. package/dist-engine-src/src/transaction/live_state_overlay.rs +0 -35
  204. package/dist-engine-src/src/transaction/mod.rs +0 -13
  205. package/dist-engine-src/src/transaction/normalization.rs +0 -890
  206. package/dist-engine-src/src/transaction/prep.rs +0 -37
  207. package/dist-engine-src/src/transaction/schema_resolver.rs +0 -149
  208. package/dist-engine-src/src/transaction/staging.rs +0 -1731
  209. package/dist-engine-src/src/transaction/types.rs +0 -460
  210. package/dist-engine-src/src/transaction/validation.rs +0 -5830
  211. package/dist-engine-src/src/untracked_state/codec.rs +0 -307
  212. package/dist-engine-src/src/untracked_state/context.rs +0 -98
  213. package/dist-engine-src/src/untracked_state/materialization.rs +0 -63
  214. package/dist-engine-src/src/untracked_state/mod.rs +0 -15
  215. package/dist-engine-src/src/untracked_state/storage.rs +0 -396
  216. package/dist-engine-src/src/untracked_state/types.rs +0 -146
  217. package/dist-engine-src/src/version/context.rs +0 -40
  218. package/dist-engine-src/src/version/lifecycle.rs +0 -221
  219. package/dist-engine-src/src/version/mod.rs +0 -13
  220. package/dist-engine-src/src/version/refs.rs +0 -330
  221. package/dist-engine-src/src/version/stage_rows.rs +0 -67
  222. package/dist-engine-src/src/version/types.rs +0 -21
  223. package/dist-engine-src/src/wasm/mod.rs +0 -60
@@ -1,63 +0,0 @@
1
- use crate::tracked_state::{
2
- TrackedStateDiffEntry, TrackedStateDiffKind, TrackedStateMergeConflict, TrackedStateMergePlan,
3
- };
4
- use crate::LixError;
5
- use serde_json::Value as JsonValue;
6
-
7
- #[derive(Debug, Clone, PartialEq, Eq)]
8
- pub(crate) struct MergeConflict {
9
- pub(crate) kind: MergeConflictKind,
10
- pub(crate) schema_key: String,
11
- pub(crate) entity_id: JsonValue,
12
- pub(crate) file_id: Option<String>,
13
- pub(crate) target: MergeConflictSide,
14
- pub(crate) source: MergeConflictSide,
15
- }
16
-
17
- #[derive(Debug, Clone, Copy, PartialEq, Eq)]
18
- pub(crate) enum MergeConflictKind {
19
- SameEntityChanged,
20
- }
21
-
22
- #[derive(Debug, Clone, PartialEq, Eq)]
23
- pub(crate) struct MergeConflictSide {
24
- pub(crate) kind: MergeConflictChangeKind,
25
- pub(crate) before_change_id: Option<String>,
26
- pub(crate) after_change_id: Option<String>,
27
- }
28
-
29
- #[derive(Debug, Clone, Copy, PartialEq, Eq)]
30
- pub(crate) enum MergeConflictChangeKind {
31
- Added,
32
- Modified,
33
- Removed,
34
- }
35
-
36
- pub(crate) fn conflicts_from_plan(
37
- plan: &TrackedStateMergePlan,
38
- ) -> Result<Vec<MergeConflict>, LixError> {
39
- plan.conflicts.iter().map(conflict_from_tracked).collect()
40
- }
41
-
42
- fn conflict_from_tracked(conflict: &TrackedStateMergeConflict) -> Result<MergeConflict, LixError> {
43
- Ok(MergeConflict {
44
- kind: MergeConflictKind::SameEntityChanged,
45
- schema_key: conflict.identity.schema_key.clone(),
46
- entity_id: conflict.identity.entity_id.as_json_array_value()?,
47
- file_id: conflict.identity.file_id.clone(),
48
- target: conflict_side_from_diff_entry(&conflict.target),
49
- source: conflict_side_from_diff_entry(&conflict.source),
50
- })
51
- }
52
-
53
- fn conflict_side_from_diff_entry(entry: &TrackedStateDiffEntry) -> MergeConflictSide {
54
- MergeConflictSide {
55
- kind: match entry.kind {
56
- TrackedStateDiffKind::Added => MergeConflictChangeKind::Added,
57
- TrackedStateDiffKind::Modified => MergeConflictChangeKind::Modified,
58
- TrackedStateDiffKind::Removed => MergeConflictChangeKind::Removed,
59
- },
60
- before_change_id: entry.before.as_ref().map(|row| row.change_id.clone()),
61
- after_change_id: entry.after.as_ref().map(|row| row.change_id.clone()),
62
- }
63
- }
@@ -1,11 +0,0 @@
1
- mod analysis;
2
- mod apply;
3
- mod conflicts;
4
- mod stats;
5
- mod version;
6
-
7
- pub use version::{
8
- MergeChangeStats, MergeConflict, MergeConflictChangeKind, MergeConflictKind, MergeConflictSide,
9
- MergeVersionOptions, MergeVersionOutcome, MergeVersionPreview, MergeVersionPreviewOptions,
10
- MergeVersionReceipt,
11
- };
@@ -1,65 +0,0 @@
1
- use crate::tracked_state::{
2
- TrackedStateDiff, TrackedStateDiffKind, TrackedStateMergePatch, TrackedStateMergePlan,
3
- };
4
- use crate::LixError;
5
-
6
- #[derive(Debug, Clone, PartialEq, Eq, Default)]
7
- pub(crate) struct MergeStats {
8
- pub(crate) total: usize,
9
- pub(crate) added: usize,
10
- pub(crate) modified: usize,
11
- pub(crate) removed: usize,
12
- }
13
-
14
- pub(crate) fn stats_from_diff(diff: &TrackedStateDiff) -> MergeStats {
15
- let mut stats = MergeStats::default();
16
- for entry in &diff.entries {
17
- stats.add(entry.kind);
18
- }
19
- stats
20
- }
21
-
22
- pub(crate) fn stats_from_plan(
23
- plan: &TrackedStateMergePlan,
24
- source_diff: &TrackedStateDiff,
25
- ) -> Result<MergeStats, LixError> {
26
- let mut stats = MergeStats::default();
27
- for patch in &plan.patches {
28
- let identity = patch_identity(patch);
29
- let Some(entry) = source_diff
30
- .entries
31
- .iter()
32
- .find(|entry| &entry.identity == identity)
33
- else {
34
- return Err(LixError::new(
35
- "LIX_ERROR_UNKNOWN",
36
- format!(
37
- "merge analysis could not find source diff entry for adopted schema '{}' entity '{}'",
38
- identity.schema_key,
39
- identity.entity_id.as_json_array_text()?
40
- ),
41
- ));
42
- };
43
- stats.add(entry.kind);
44
- }
45
- Ok(stats)
46
- }
47
-
48
- impl MergeStats {
49
- fn add(&mut self, kind: TrackedStateDiffKind) {
50
- self.total += 1;
51
- match kind {
52
- TrackedStateDiffKind::Added => self.added += 1,
53
- TrackedStateDiffKind::Modified => self.modified += 1,
54
- TrackedStateDiffKind::Removed => self.removed += 1,
55
- }
56
- }
57
- }
58
-
59
- fn patch_identity(
60
- patch: &TrackedStateMergePatch,
61
- ) -> &crate::tracked_state::TrackedStateDiffIdentity {
62
- match patch {
63
- TrackedStateMergePatch::Adopt { identity, .. } => identity,
64
- }
65
- }
@@ -1,427 +0,0 @@
1
- use serde_json::{json, Value as JsonValue};
2
-
3
- use crate::transaction::types::TransactionWrite;
4
- use crate::version::{VersionLifecycle, VersionOperation, VersionReferenceRole};
5
- use crate::LixError;
6
-
7
- use super::analysis::{analyze, MergeCommits, MergeOutcome};
8
- use super::apply::adopted_changes_from_merge_plan;
9
- use super::conflicts::{
10
- MergeConflict as AnalysisMergeConflict,
11
- MergeConflictChangeKind as AnalysisMergeConflictChangeKind,
12
- MergeConflictKind as AnalysisMergeConflictKind, MergeConflictSide as AnalysisMergeConflictSide,
13
- };
14
- use super::stats::MergeStats;
15
- use crate::session::context::SessionContext;
16
-
17
- /// Options for merging another version into this session's active version.
18
- #[derive(Debug, Clone, PartialEq, Eq)]
19
- pub struct MergeVersionOptions {
20
- /// Version whose changes should be merged into the active session version.
21
- pub source_version_id: String,
22
- }
23
-
24
- /// Options for previewing a merge from another version into this session's
25
- /// active version.
26
- #[derive(Debug, Clone, PartialEq, Eq)]
27
- pub struct MergeVersionPreviewOptions {
28
- /// Version whose changes would be merged into the active session version.
29
- pub source_version_id: String,
30
- }
31
-
32
- /// Receipt returned after merging a version.
33
- #[derive(Debug, Clone, PartialEq, Eq)]
34
- pub struct MergeVersionReceipt {
35
- pub outcome: MergeVersionOutcome,
36
- pub target_version_id: String,
37
- pub source_version_id: String,
38
- pub base_commit_id: String,
39
- pub target_head_before_commit_id: String,
40
- pub source_head_before_commit_id: String,
41
- pub target_head_after_commit_id: String,
42
- pub created_merge_commit_id: Option<String>,
43
- pub change_stats: MergeChangeStats,
44
- }
45
-
46
- #[derive(Debug, Clone, PartialEq, Eq, Default)]
47
- pub struct MergeChangeStats {
48
- pub total: usize,
49
- pub added: usize,
50
- pub modified: usize,
51
- pub removed: usize,
52
- }
53
-
54
- #[derive(Debug, Clone, PartialEq, Eq)]
55
- pub struct MergeVersionPreview {
56
- pub outcome: MergeVersionOutcome,
57
- pub target_version_id: String,
58
- pub source_version_id: String,
59
- pub base_commit_id: String,
60
- pub target_head_commit_id: String,
61
- pub source_head_commit_id: String,
62
- pub change_stats: MergeChangeStats,
63
- pub conflicts: Vec<MergeConflict>,
64
- }
65
-
66
- #[derive(Debug, Clone, PartialEq, Eq)]
67
- pub struct MergeConflict {
68
- pub kind: MergeConflictKind,
69
- pub schema_key: String,
70
- pub entity_id: JsonValue,
71
- pub file_id: Option<String>,
72
- pub target: MergeConflictSide,
73
- pub source: MergeConflictSide,
74
- }
75
-
76
- #[derive(Debug, Clone, Copy, PartialEq, Eq)]
77
- pub enum MergeConflictKind {
78
- SameEntityChanged,
79
- }
80
-
81
- #[derive(Debug, Clone, PartialEq, Eq)]
82
- pub struct MergeConflictSide {
83
- pub kind: MergeConflictChangeKind,
84
- pub before_change_id: Option<String>,
85
- pub after_change_id: Option<String>,
86
- }
87
-
88
- #[derive(Debug, Clone, Copy, PartialEq, Eq)]
89
- pub enum MergeConflictChangeKind {
90
- Added,
91
- Modified,
92
- Removed,
93
- }
94
-
95
- #[derive(Debug, Clone, Copy, PartialEq, Eq)]
96
- pub enum MergeVersionOutcome {
97
- AlreadyUpToDate,
98
- FastForward,
99
- MergeCommitted,
100
- }
101
-
102
- impl SessionContext {
103
- /// Previews merging `source_version_id` into this session's active version
104
- /// without advancing refs, staging changes, or creating commits.
105
- pub async fn merge_version_preview(
106
- &self,
107
- options: MergeVersionPreviewOptions,
108
- ) -> Result<MergeVersionPreview, LixError> {
109
- let source_version_id = options.source_version_id;
110
-
111
- self.with_write_transaction(|transaction| {
112
- Box::pin(async move {
113
- let active_version_id = transaction.active_version_id().to_string();
114
- if source_version_id == active_version_id {
115
- return Err(LixError::invalid_self_merge(active_version_id));
116
- }
117
-
118
- let (target_head, source_head) = {
119
- let reader = transaction.version_ref_reader();
120
- let lifecycle = VersionLifecycle::new(&reader);
121
- let target_head = lifecycle
122
- .require_existing_commit_id(
123
- &active_version_id,
124
- VersionOperation::MergeVersionPreview,
125
- VersionReferenceRole::Target,
126
- )
127
- .await?;
128
- let source_head = lifecycle
129
- .require_existing_commit_id(
130
- &source_version_id,
131
- VersionOperation::MergeVersionPreview,
132
- VersionReferenceRole::Source,
133
- )
134
- .await?;
135
- (target_head, source_head)
136
- };
137
-
138
- let merge_base = {
139
- let mut reader = transaction.commit_graph_reader();
140
- reader.merge_base(&target_head, &source_head).await?
141
- };
142
-
143
- let analysis = {
144
- let mut reader = transaction.tracked_state_reader();
145
- analyze(
146
- &mut reader,
147
- MergeCommits {
148
- base_commit_id: merge_base.commit_id,
149
- target_commit_id: target_head,
150
- source_commit_id: source_head,
151
- },
152
- )
153
- .await?
154
- };
155
-
156
- Ok(preview_from_analysis(
157
- &active_version_id,
158
- &source_version_id,
159
- &analysis,
160
- ))
161
- })
162
- })
163
- .await
164
- }
165
-
166
- /// Merges `source_version_id` into this session's active version.
167
- ///
168
- /// The generated target commit keeps the previous target head as its first
169
- /// parent and records the source head as an additional parent, so the
170
- /// commit graph preserves branch ancestry while tracked-state storage can
171
- /// build the new root by applying source effects onto the target root.
172
- pub async fn merge_version(
173
- &self,
174
- options: MergeVersionOptions,
175
- ) -> Result<MergeVersionReceipt, LixError> {
176
- let source_version_id = options.source_version_id;
177
-
178
- self.with_write_transaction(|transaction| {
179
- Box::pin(async move {
180
- let active_version_id = transaction.active_version_id().to_string();
181
- if source_version_id == active_version_id {
182
- return Err(LixError::invalid_self_merge(active_version_id));
183
- }
184
-
185
- let (target_head, source_head) = {
186
- let reader = transaction.version_ref_reader();
187
- let lifecycle = VersionLifecycle::new(&reader);
188
- let target_head = lifecycle
189
- .require_existing_commit_id(
190
- &active_version_id,
191
- VersionOperation::MergeVersion,
192
- VersionReferenceRole::Target,
193
- )
194
- .await?;
195
- let source_head = lifecycle
196
- .require_existing_commit_id(
197
- &source_version_id,
198
- VersionOperation::MergeVersion,
199
- VersionReferenceRole::Source,
200
- )
201
- .await?;
202
- (target_head, source_head)
203
- };
204
-
205
- let merge_base = {
206
- let mut reader = transaction.commit_graph_reader();
207
- reader.merge_base(&target_head, &source_head).await?
208
- };
209
- let base_commit_id = merge_base.commit_id;
210
-
211
- let analysis = {
212
- let mut reader = transaction.tracked_state_reader();
213
- analyze(
214
- &mut reader,
215
- MergeCommits {
216
- base_commit_id,
217
- target_commit_id: target_head,
218
- source_commit_id: source_head,
219
- },
220
- )
221
- .await?
222
- };
223
-
224
- if analysis.outcome == MergeOutcome::AlreadyUpToDate {
225
- return Ok(MergeVersionReceipt {
226
- outcome: MergeVersionOutcome::AlreadyUpToDate,
227
- target_version_id: active_version_id,
228
- source_version_id,
229
- base_commit_id: analysis.commits.base_commit_id,
230
- target_head_after_commit_id: analysis.commits.target_commit_id.clone(),
231
- target_head_before_commit_id: analysis.commits.target_commit_id,
232
- source_head_before_commit_id: analysis.commits.source_commit_id,
233
- created_merge_commit_id: None,
234
- change_stats: merge_change_stats_from_analysis(&analysis.stats),
235
- });
236
- }
237
-
238
- if analysis.outcome == MergeOutcome::FastForward {
239
- transaction
240
- .advance_version_ref(&active_version_id, &analysis.commits.source_commit_id)
241
- .await?;
242
-
243
- return Ok(MergeVersionReceipt {
244
- outcome: MergeVersionOutcome::FastForward,
245
- target_version_id: active_version_id,
246
- source_version_id,
247
- base_commit_id: analysis.commits.base_commit_id,
248
- target_head_before_commit_id: analysis.commits.target_commit_id,
249
- source_head_before_commit_id: analysis.commits.source_commit_id.clone(),
250
- target_head_after_commit_id: analysis.commits.source_commit_id,
251
- created_merge_commit_id: None,
252
- change_stats: merge_change_stats_from_analysis(&analysis.stats),
253
- });
254
- }
255
-
256
- let merge_plan = analysis
257
- .merge_plan()
258
- .expect("merge analysis should include a plan for mergeCommitted");
259
-
260
- if !analysis.conflicts.is_empty() {
261
- return Err(merge_conflict_error(
262
- &analysis
263
- .conflicts
264
- .iter()
265
- .map(merge_conflict_from_analysis)
266
- .collect::<Vec<_>>(),
267
- )?);
268
- }
269
-
270
- let adopted_changes =
271
- adopted_changes_from_merge_plan(merge_plan, &active_version_id);
272
- if adopted_changes.is_empty() {
273
- let created_merge_commit_id =
274
- transaction.stage_empty_commit(active_version_id.clone())?;
275
- transaction.add_commit_parent(
276
- active_version_id.clone(),
277
- analysis.commits.source_commit_id.clone(),
278
- )?;
279
- return Ok(MergeVersionReceipt {
280
- outcome: MergeVersionOutcome::MergeCommitted,
281
- target_version_id: active_version_id,
282
- source_version_id,
283
- base_commit_id: analysis.commits.base_commit_id,
284
- target_head_after_commit_id: created_merge_commit_id.clone(),
285
- target_head_before_commit_id: analysis.commits.target_commit_id,
286
- source_head_before_commit_id: analysis.commits.source_commit_id,
287
- created_merge_commit_id: Some(created_merge_commit_id),
288
- change_stats: merge_change_stats_from_analysis(&analysis.stats),
289
- });
290
- }
291
-
292
- transaction
293
- .stage_write(TransactionWrite::AdoptedChanges {
294
- changes: adopted_changes,
295
- })
296
- .await?;
297
- let created_merge_commit_id = transaction
298
- .staged_commit_id(&active_version_id)?
299
- .ok_or_else(|| {
300
- LixError::new(
301
- "LIX_ERROR_UNKNOWN",
302
- "merge_version staged tracked rows without a commit id",
303
- )
304
- })?;
305
- transaction.add_commit_parent(
306
- active_version_id.clone(),
307
- analysis.commits.source_commit_id.clone(),
308
- )?;
309
-
310
- Ok(MergeVersionReceipt {
311
- outcome: MergeVersionOutcome::MergeCommitted,
312
- target_version_id: active_version_id,
313
- source_version_id,
314
- base_commit_id: analysis.commits.base_commit_id,
315
- target_head_before_commit_id: analysis.commits.target_commit_id,
316
- source_head_before_commit_id: analysis.commits.source_commit_id,
317
- created_merge_commit_id: Some(created_merge_commit_id.clone()),
318
- target_head_after_commit_id: created_merge_commit_id,
319
- change_stats: merge_change_stats_from_analysis(&analysis.stats),
320
- })
321
- })
322
- })
323
- .await
324
- }
325
- }
326
-
327
- fn preview_from_analysis(
328
- target_version_id: &str,
329
- source_version_id: &str,
330
- analysis: &super::analysis::MergeAnalysis,
331
- ) -> MergeVersionPreview {
332
- MergeVersionPreview {
333
- outcome: merge_version_outcome_from_analysis(analysis.outcome),
334
- target_version_id: target_version_id.to_string(),
335
- source_version_id: source_version_id.to_string(),
336
- base_commit_id: analysis.commits.base_commit_id.clone(),
337
- target_head_commit_id: analysis.commits.target_commit_id.clone(),
338
- source_head_commit_id: analysis.commits.source_commit_id.clone(),
339
- change_stats: merge_change_stats_from_analysis(&analysis.stats),
340
- conflicts: analysis
341
- .conflicts
342
- .iter()
343
- .map(merge_conflict_from_analysis)
344
- .collect(),
345
- }
346
- }
347
-
348
- fn merge_version_outcome_from_analysis(outcome: MergeOutcome) -> MergeVersionOutcome {
349
- match outcome {
350
- MergeOutcome::AlreadyUpToDate => MergeVersionOutcome::AlreadyUpToDate,
351
- MergeOutcome::FastForward => MergeVersionOutcome::FastForward,
352
- MergeOutcome::MergeCommitted => MergeVersionOutcome::MergeCommitted,
353
- }
354
- }
355
-
356
- fn merge_change_stats_from_analysis(stats: &MergeStats) -> MergeChangeStats {
357
- MergeChangeStats {
358
- total: stats.total,
359
- added: stats.added,
360
- modified: stats.modified,
361
- removed: stats.removed,
362
- }
363
- }
364
-
365
- fn merge_conflict_from_analysis(conflict: &AnalysisMergeConflict) -> MergeConflict {
366
- MergeConflict {
367
- kind: match conflict.kind {
368
- AnalysisMergeConflictKind::SameEntityChanged => MergeConflictKind::SameEntityChanged,
369
- },
370
- schema_key: conflict.schema_key.clone(),
371
- entity_id: conflict.entity_id.clone(),
372
- file_id: conflict.file_id.clone(),
373
- target: merge_conflict_side_from_analysis(&conflict.target),
374
- source: merge_conflict_side_from_analysis(&conflict.source),
375
- }
376
- }
377
-
378
- fn merge_conflict_side_from_analysis(side: &AnalysisMergeConflictSide) -> MergeConflictSide {
379
- MergeConflictSide {
380
- kind: match side.kind {
381
- AnalysisMergeConflictChangeKind::Added => MergeConflictChangeKind::Added,
382
- AnalysisMergeConflictChangeKind::Modified => MergeConflictChangeKind::Modified,
383
- AnalysisMergeConflictChangeKind::Removed => MergeConflictChangeKind::Removed,
384
- },
385
- before_change_id: side.before_change_id.clone(),
386
- after_change_id: side.after_change_id.clone(),
387
- }
388
- }
389
-
390
- fn merge_conflict_error(conflicts: &[MergeConflict]) -> Result<LixError, LixError> {
391
- let conflict_count = conflicts.len();
392
- Ok(LixError::new(
393
- LixError::CODE_MERGE_CONFLICT,
394
- format!("merge_version found {conflict_count} tracked-state conflict(s)"),
395
- )
396
- .with_hint("Resolve the conflicting entities in the target version, then retry the merge.")
397
- .with_details(json!({
398
- "conflicts": conflicts.iter()
399
- .map(merge_conflict_details)
400
- .collect::<Vec<_>>(),
401
- })))
402
- }
403
-
404
- fn merge_conflict_details(conflict: &MergeConflict) -> serde_json::Value {
405
- json!({
406
- "kind": match conflict.kind {
407
- MergeConflictKind::SameEntityChanged => "sameEntityChanged",
408
- },
409
- "schemaKey": conflict.schema_key,
410
- "entityId": conflict.entity_id,
411
- "fileId": conflict.file_id,
412
- "target": merge_conflict_side_details(&conflict.target),
413
- "source": merge_conflict_side_details(&conflict.source),
414
- })
415
- }
416
-
417
- fn merge_conflict_side_details(side: &MergeConflictSide) -> serde_json::Value {
418
- json!({
419
- "kind": match side.kind {
420
- MergeConflictChangeKind::Added => "added",
421
- MergeConflictChangeKind::Modified => "modified",
422
- MergeConflictChangeKind::Removed => "removed",
423
- },
424
- "beforeChangeId": side.before_change_id,
425
- "afterChangeId": side.after_change_id,
426
- })
427
- }
@@ -1,27 +0,0 @@
1
- //! Engine session boundary.
2
- //!
3
- //! Transaction invariant: a session has one execution lease. Parent-handle
4
- //! calls use it for implicit single-statement execution; explicit transactions
5
- //! hold it until commit or rollback. Session APIs must not open `Transaction`
6
- //! directly or use session-level read helpers inside write flows.
7
-
8
- mod context;
9
- mod create_version;
10
- mod execute;
11
- mod merge;
12
- #[cfg(feature = "storage-benches")]
13
- pub mod optimization9_sql2_bench;
14
- mod switch_version;
15
- mod transaction;
16
-
17
- pub use context::SessionContext;
18
- pub(crate) use context::{SessionMode, WORKSPACE_VERSION_KEY};
19
- pub use create_version::{CreateVersionOptions, CreateVersionReceipt};
20
- pub use execute::{ExecuteResult, Row, RowRef, TryFromValue};
21
- pub use merge::{
22
- MergeChangeStats, MergeConflict, MergeConflictChangeKind, MergeConflictKind, MergeConflictSide,
23
- MergeVersionOptions, MergeVersionOutcome, MergeVersionPreview, MergeVersionPreviewOptions,
24
- MergeVersionReceipt,
25
- };
26
- pub use switch_version::{SwitchVersionOptions, SwitchVersionReceipt};
27
- pub use transaction::SessionTransaction;
@@ -1,100 +0,0 @@
1
- use crate::functions::FunctionContext;
2
- use crate::session::context::{SessionContext, SessionSqlExecutionContext};
3
- use crate::sql2::{self, SqlLogicalPlan};
4
- use crate::storage::StorageReadScope;
5
- use crate::transaction::open_transaction;
6
- use crate::{LixError, SqlQueryResult, Value};
7
-
8
- /// Opaque read plan used by the Optimization 9 SQL2 diagnostic benchmark.
9
- ///
10
- /// This module is gated behind `storage-benches` and exists only to split SQL2
11
- /// planning cost from SQL2 execution cost without widening the normal session
12
- /// API.
13
- pub struct PreparedReadPlan {
14
- plan: SqlLogicalPlan,
15
- read_scope:
16
- StorageReadScope<Box<dyn crate::storage::StorageReadTransaction + Send + Sync + 'static>>,
17
- runtime_functions: FunctionContext,
18
- }
19
-
20
- pub async fn plan_read_only(session: &SessionContext, sql: &str) -> Result<(), LixError> {
21
- let prepared = prepare_read_plan(session, sql).await?;
22
- drop(prepared.plan);
23
- drop(prepared.runtime_functions);
24
- prepared.read_scope.rollback().await
25
- }
26
-
27
- pub async fn plan_write_only(session: &SessionContext, sql: &str) -> Result<(), LixError> {
28
- session.ensure_open()?;
29
- let opened = open_transaction(
30
- &session.mode,
31
- session.storage.clone(),
32
- std::sync::Arc::clone(&session.live_state),
33
- std::sync::Arc::clone(&session.tracked_state),
34
- std::sync::Arc::clone(&session.binary_cas),
35
- std::sync::Arc::clone(&session.commit_store),
36
- std::sync::Arc::clone(&session.version_ctx),
37
- std::sync::Arc::clone(&session.catalog_context),
38
- )
39
- .await?;
40
- let mut transaction = opened.transaction;
41
- let runtime_functions = opened.runtime_functions;
42
- let plan = sql2::create_write_logical_plan(&mut transaction, sql).await?;
43
- drop(plan);
44
- drop(runtime_functions);
45
- transaction.rollback().await
46
- }
47
-
48
- pub async fn prepare_read_plan(
49
- session: &SessionContext,
50
- sql: &str,
51
- ) -> Result<PreparedReadPlan, LixError> {
52
- session.ensure_open()?;
53
- let read_scope = StorageReadScope::new(session.storage.begin_read_transaction().await?);
54
- let mut read_store = read_scope.store();
55
- let live_state: std::sync::Arc<dyn crate::live_state::LiveStateReader> =
56
- std::sync::Arc::new(session.live_state.reader(read_store.clone()));
57
- let runtime_functions = FunctionContext::prepare(live_state.as_ref()).await?;
58
- let functions = runtime_functions.provider();
59
- let active_version_id = session
60
- .active_version_id_from_reader(&mut read_store)
61
- .await?;
62
- let visible_schemas = session
63
- .catalog_context
64
- .schema_jsons_for_sql_read_planning(live_state.as_ref(), &active_version_id)
65
- .await?;
66
- let ctx = SessionSqlExecutionContext {
67
- active_version_id: &active_version_id,
68
- read_store,
69
- live_state: std::sync::Arc::clone(&session.live_state),
70
- binary_cas: std::sync::Arc::clone(&session.binary_cas),
71
- commit_store: std::sync::Arc::clone(&session.commit_store),
72
- version_ctx: std::sync::Arc::clone(&session.version_ctx),
73
- visible_schemas,
74
- functions: functions.clone(),
75
- };
76
- let plan = sql2::create_logical_plan(&ctx, sql).await?;
77
- drop(ctx);
78
- drop(live_state);
79
-
80
- Ok(PreparedReadPlan {
81
- plan,
82
- read_scope,
83
- runtime_functions,
84
- })
85
- }
86
-
87
- pub async fn execute_read_plan(
88
- prepared: PreparedReadPlan,
89
- params: &[Value],
90
- ) -> Result<SqlQueryResult, LixError> {
91
- let PreparedReadPlan {
92
- plan,
93
- read_scope,
94
- runtime_functions,
95
- } = prepared;
96
- let result = sql2::execute_logical_plan(plan, params).await;
97
- read_scope.rollback().await?;
98
- drop(runtime_functions);
99
- result
100
- }