@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,619 +0,0 @@
1
- //! Plugin install write helpers.
2
- //!
3
- //! This module owns plugin archive parsing, registered-schema staging, and the
4
- //! prepared write construction needed to install a plugin into the engine.
5
-
6
- use std::collections::BTreeMap;
7
-
8
- use async_trait::async_trait;
9
- use serde_json::{json, Value as JsonValue};
10
-
11
- use crate::catalog::{ResolvedRelation, SurfaceRegistry};
12
- use crate::common::stable_content_fingerprint_hex;
13
- use crate::common::{NormalizedDirectoryPath, ParsedFilePath};
14
- use crate::plugin::{
15
- parse_plugin_archive_for_install, plugin_storage_archive_file_id, plugin_storage_archive_path,
16
- ParsedPluginArchive, PLUGIN_STORAGE_ROOT_DIRECTORY_PATH,
17
- };
18
- use crate::schema::{schema_key_from_definition, validate_lix_schema_definition};
19
- use crate::sql::{
20
- ChangeBatch, CommitPreconditions, ExpectedHead, IdempotencyKey, OptionalTextPatch, PlanEffects,
21
- PlannedFilesystemDescriptor, PlannedFilesystemFile, PlannedFilesystemState, PlannedStateRow,
22
- PreparedWriteOperationKind, PreparedWriteStatementKind, PublicChange, ResultContract,
23
- SchemaLiveTableRequirement, SemanticEffect, WriteDiagnosticContext, WriteLane, WriteMode,
24
- };
25
- use crate::streams::{
26
- state_commit_stream_changes_from_changes, StateCommitStreamOperation,
27
- StateCommitStreamRuntimeMetadata,
28
- };
29
- use crate::transaction::{
30
- PreparedPublicSurfaceRegistryEffect, PreparedPublicSurfaceRegistryMutation,
31
- PreparedPublicWrite, PreparedPublicWriteContract, PreparedPublicWriteExecution,
32
- PreparedPublicWriteMaterialization, PreparedPublicWritePlanArtifact,
33
- PreparedResolvedWritePartition, PreparedResolvedWritePlan, PreparedWriteArtifact,
34
- PreparedWriteFunctionBindings, PreparedWriteStatement,
35
- };
36
- use crate::{LixError, Value};
37
-
38
- use crate::transaction::WriteCommand;
39
- const REGISTERED_SCHEMA_STORAGE_SCHEMA_KEY: &str = "lix_registered_schema";
40
- const FILESYSTEM_DESCRIPTOR_SCHEMA_KEY: &str = "lix_file_descriptor";
41
- const FILESYSTEM_BINARY_BLOB_REF_SCHEMA_KEY: &str = "lix_binary_blob_ref";
42
-
43
- #[derive(Clone)]
44
- pub(crate) struct PluginInstallWriteContext {
45
- function_bindings: PreparedWriteFunctionBindings,
46
- public_surface_registry: SurfaceRegistry,
47
- target_version_id: String,
48
- active_account_ids: Vec<String>,
49
- origin_key: Option<String>,
50
- }
51
-
52
- impl PluginInstallWriteContext {
53
- pub(crate) fn new(
54
- function_bindings: PreparedWriteFunctionBindings,
55
- public_surface_registry: SurfaceRegistry,
56
- target_version_id: impl Into<String>,
57
- active_account_ids: Vec<String>,
58
- origin_key: Option<String>,
59
- ) -> Self {
60
- Self {
61
- function_bindings,
62
- public_surface_registry,
63
- target_version_id: target_version_id.into(),
64
- active_account_ids,
65
- origin_key,
66
- }
67
- }
68
-
69
- fn target_version_id(&self) -> &str {
70
- &self.target_version_id
71
- }
72
- }
73
-
74
- #[async_trait(?Send)]
75
- pub(crate) trait PluginInstallWriteExecutor {
76
- fn plugin_install_write_context(&self) -> PluginInstallWriteContext;
77
-
78
- fn stage_prepared_write_statement(&mut self, statement: WriteCommand) -> Result<(), LixError>;
79
-
80
- async fn resolve_directory_id(
81
- &mut self,
82
- path: &NormalizedDirectoryPath,
83
- ) -> Result<Option<String>, LixError>;
84
- }
85
-
86
- pub(crate) async fn install_plugin_archive_with_writer(
87
- archive_bytes: &[u8],
88
- executor: &mut dyn PluginInstallWriteExecutor,
89
- ) -> Result<(), LixError> {
90
- let parsed = parse_plugin_archive_for_install(archive_bytes)?;
91
- install_plugin_with_writer(executor, &parsed, archive_bytes).await
92
- }
93
-
94
- pub(crate) fn prepare_registered_schema_write_statement(
95
- schema: &JsonValue,
96
- context: &PluginInstallWriteContext,
97
- ) -> Result<WriteCommand, LixError> {
98
- prepare_registered_schema_write_statement_from_schemas(std::slice::from_ref(schema), context)
99
- }
100
-
101
- async fn install_plugin_with_writer(
102
- executor: &mut dyn PluginInstallWriteExecutor,
103
- parsed: &ParsedPluginArchive,
104
- archive_bytes: &[u8],
105
- ) -> Result<(), LixError> {
106
- let plugin_install_context = executor.plugin_install_write_context();
107
-
108
- if !parsed.schemas.is_empty() {
109
- executor.stage_prepared_write_statement(
110
- prepare_registered_schema_write_statement_from_schemas(
111
- &parsed.schemas,
112
- &plugin_install_context,
113
- )?,
114
- )?;
115
- }
116
-
117
- let plugin_root =
118
- NormalizedDirectoryPath::from_normalized(PLUGIN_STORAGE_ROOT_DIRECTORY_PATH.to_string());
119
- let plugin_directory_id = executor
120
- .resolve_directory_id(&plugin_root)
121
- .await?
122
- .ok_or_else(|| {
123
- LixError::new(
124
- "LIX_ERROR_UNKNOWN",
125
- format!(
126
- "plugin storage directory '{}' is missing",
127
- PLUGIN_STORAGE_ROOT_DIRECTORY_PATH
128
- ),
129
- )
130
- })?;
131
- executor.stage_prepared_write_statement(prepare_plugin_archive_write_statement(
132
- parsed,
133
- archive_bytes,
134
- &plugin_directory_id,
135
- &plugin_install_context,
136
- )?)?;
137
-
138
- Ok(())
139
- }
140
-
141
- #[derive(Clone)]
142
- struct RegisteredSchemaRowSpec {
143
- entity_id: String,
144
- registered_schema_key: String,
145
- snapshot: JsonValue,
146
- schema_json: JsonValue,
147
- }
148
-
149
- fn prepare_registered_schema_write_statement_from_schemas(
150
- schemas: &[JsonValue],
151
- context: &PluginInstallWriteContext,
152
- ) -> Result<WriteCommand, LixError> {
153
- let target = require_resolved_surface(
154
- &context.public_surface_registry,
155
- "lix_registered_schema_by_version",
156
- )?;
157
- let schema_rows = schemas
158
- .iter()
159
- .map(registered_schema_row_spec_from_json)
160
- .collect::<Result<Vec<_>, _>>()?;
161
- let intended_post_state = schema_rows
162
- .iter()
163
- .map(|row| registered_schema_planned_row(row, context.target_version_id()))
164
- .collect::<Vec<_>>();
165
- let changes = schema_rows
166
- .iter()
167
- .map(|row| PublicChange {
168
- entity_id: row.entity_id.clone(),
169
- schema_key: REGISTERED_SCHEMA_STORAGE_SCHEMA_KEY.to_string(),
170
- file_id: None,
171
- plugin_key: None,
172
- snapshot_content: Some(row.snapshot.to_string()),
173
- metadata: None,
174
- version_id: context.target_version_id().to_string(),
175
- origin_key: context.origin_key.clone(),
176
- })
177
- .collect::<Vec<_>>();
178
- let schema_live_table_requirements = schema_rows
179
- .iter()
180
- .map(|row| SchemaLiveTableRequirement {
181
- schema_key: row.registered_schema_key.clone(),
182
- schema_definition: Some(row.schema_json.clone()),
183
- })
184
- .collect::<Vec<_>>();
185
-
186
- prepare_public_tracked_write_statement(
187
- context,
188
- target,
189
- "lix_registered_schema_by_version",
190
- intended_post_state,
191
- PlannedFilesystemState::default(),
192
- changes,
193
- schema_live_table_requirements,
194
- PreparedPublicSurfaceRegistryEffect::ApplyMutations(
195
- schema_rows
196
- .iter()
197
- .map(
198
- |row| PreparedPublicSurfaceRegistryMutation::UpsertRegisteredSchemaSnapshot {
199
- snapshot: row.snapshot.clone(),
200
- },
201
- )
202
- .collect(),
203
- ),
204
- "semantic.register_schema",
205
- )
206
- }
207
-
208
- fn prepare_plugin_archive_write_statement(
209
- parsed: &ParsedPluginArchive,
210
- archive_bytes: &[u8],
211
- plugin_directory_id: &str,
212
- context: &PluginInstallWriteContext,
213
- ) -> Result<WriteCommand, LixError> {
214
- let target = require_resolved_surface(&context.public_surface_registry, "lix_file_by_version")?;
215
- let archive_id = plugin_storage_archive_file_id(parsed.manifest.key.as_str());
216
- let archive_path = plugin_storage_archive_path(parsed.manifest.key.as_str())?;
217
- let parsed_path = ParsedFilePath::try_from_path(&archive_path)?;
218
- let descriptor = PlannedFilesystemDescriptor {
219
- directory_id: plugin_directory_id.to_string(),
220
- name: parsed_path.name.clone(),
221
- metadata: None,
222
- hidden: false,
223
- };
224
- let target_version_id = context.target_version_id();
225
- let filesystem_state = PlannedFilesystemState {
226
- files: [(
227
- (archive_id.clone(), target_version_id.to_string()),
228
- PlannedFilesystemFile {
229
- file_id: archive_id.clone(),
230
- version_id: target_version_id.to_string(),
231
- untracked: false,
232
- descriptor: Some(descriptor.clone()),
233
- metadata_patch: OptionalTextPatch::Unchanged,
234
- data: Some(archive_bytes.to_vec()),
235
- deleted: false,
236
- },
237
- )]
238
- .into_iter()
239
- .collect(),
240
- };
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)?,
244
- ];
245
- let changes = intended_post_state
246
- .iter()
247
- .map(planned_row_to_public_change)
248
- .collect::<Result<Vec<_>, _>>()?;
249
-
250
- prepare_public_tracked_write_statement(
251
- context,
252
- target,
253
- "lix_file_by_version",
254
- intended_post_state,
255
- filesystem_state,
256
- changes,
257
- Vec::new(),
258
- PreparedPublicSurfaceRegistryEffect::None,
259
- "semantic.install_plugin_archive",
260
- )
261
- }
262
-
263
- fn registered_schema_row_spec_from_json(
264
- schema: &JsonValue,
265
- ) -> Result<RegisteredSchemaRowSpec, LixError> {
266
- validate_lix_schema_definition(schema)?;
267
- let schema_key = schema_key_from_definition(schema)?;
268
- Ok(RegisteredSchemaRowSpec {
269
- entity_id: schema_key.entity_id(),
270
- registered_schema_key: schema_key.schema_key,
271
- snapshot: json!({ "value": schema }),
272
- schema_json: schema.clone(),
273
- })
274
- }
275
-
276
- fn registered_schema_planned_row(
277
- row: &RegisteredSchemaRowSpec,
278
- target_version_id: &str,
279
- ) -> PlannedStateRow {
280
- let mut values = BTreeMap::new();
281
- values.insert("entity_id".to_string(), Value::Text(row.entity_id.clone()));
282
- values.insert(
283
- "schema_key".to_string(),
284
- Value::Text(REGISTERED_SCHEMA_STORAGE_SCHEMA_KEY.to_string()),
285
- );
286
- values.insert("file_id".to_string(), Value::Null);
287
- values.insert("plugin_key".to_string(), Value::Null);
288
- values.insert(
289
- "snapshot_content".to_string(),
290
- Value::Json(row.snapshot.clone()),
291
- );
292
- values.insert(
293
- "version_id".to_string(),
294
- Value::Text(target_version_id.to_string()),
295
- );
296
- PlannedStateRow {
297
- entity_id: row.entity_id.clone(),
298
- schema_key: REGISTERED_SCHEMA_STORAGE_SCHEMA_KEY.to_string(),
299
- version_id: Some(target_version_id.to_string()),
300
- values,
301
- origin_key: None,
302
- tombstone: false,
303
- }
304
- }
305
-
306
- fn plugin_archive_file_descriptor_row(
307
- archive_id: &str,
308
- target_version_id: &str,
309
- descriptor: &PlannedFilesystemDescriptor,
310
- ) -> PlannedStateRow {
311
- let snapshot_content = json!({
312
- "id": archive_id,
313
- "directory_id": descriptor.directory_id,
314
- "name": descriptor.name,
315
- "hidden": descriptor.hidden,
316
- })
317
- .to_string();
318
- let mut values = BTreeMap::new();
319
- values.insert("entity_id".to_string(), Value::Text(archive_id.to_string()));
320
- values.insert(
321
- "schema_key".to_string(),
322
- Value::Text(FILESYSTEM_DESCRIPTOR_SCHEMA_KEY.to_string()),
323
- );
324
- values.insert("file_id".to_string(), Value::Null);
325
- values.insert("plugin_key".to_string(), Value::Null);
326
- values.insert(
327
- "snapshot_content".to_string(),
328
- Value::Text(snapshot_content),
329
- );
330
- values.insert(
331
- "version_id".to_string(),
332
- Value::Text(target_version_id.to_string()),
333
- );
334
- PlannedStateRow {
335
- entity_id: archive_id.to_string(),
336
- schema_key: FILESYSTEM_DESCRIPTOR_SCHEMA_KEY.to_string(),
337
- version_id: Some(target_version_id.to_string()),
338
- values,
339
- origin_key: None,
340
- tombstone: false,
341
- }
342
- }
343
-
344
- fn plugin_archive_binary_blob_ref_row(
345
- archive_id: &str,
346
- target_version_id: &str,
347
- archive_bytes: &[u8],
348
- ) -> Result<PlannedStateRow, LixError> {
349
- let size_bytes = u64::try_from(archive_bytes.len()).map_err(|_| {
350
- LixError::new(
351
- "LIX_ERROR_UNKNOWN",
352
- format!(
353
- "plugin archive '{}' exceeds supported size range",
354
- archive_id
355
- ),
356
- )
357
- })?;
358
- let snapshot_content = json!({
359
- "id": archive_id,
360
- "blob_hash": stable_content_fingerprint_hex(archive_bytes),
361
- "size_bytes": size_bytes,
362
- })
363
- .to_string();
364
- let mut values = BTreeMap::new();
365
- values.insert("entity_id".to_string(), Value::Text(archive_id.to_string()));
366
- values.insert(
367
- "schema_key".to_string(),
368
- Value::Text(FILESYSTEM_BINARY_BLOB_REF_SCHEMA_KEY.to_string()),
369
- );
370
- values.insert("file_id".to_string(), Value::Text(archive_id.to_string()));
371
- values.insert("plugin_key".to_string(), Value::Null);
372
- values.insert(
373
- "snapshot_content".to_string(),
374
- Value::Text(snapshot_content),
375
- );
376
- values.insert(
377
- "version_id".to_string(),
378
- Value::Text(target_version_id.to_string()),
379
- );
380
- Ok(PlannedStateRow {
381
- entity_id: archive_id.to_string(),
382
- schema_key: FILESYSTEM_BINARY_BLOB_REF_SCHEMA_KEY.to_string(),
383
- version_id: Some(target_version_id.to_string()),
384
- values,
385
- origin_key: None,
386
- tombstone: false,
387
- })
388
- }
389
-
390
- fn prepare_public_tracked_write_statement(
391
- context: &PluginInstallWriteContext,
392
- target: ResolvedRelation,
393
- relation_name: &str,
394
- intended_post_state: Vec<PlannedStateRow>,
395
- filesystem_state: PlannedFilesystemState,
396
- changes: Vec<PublicChange>,
397
- schema_live_table_requirements: Vec<SchemaLiveTableRequirement>,
398
- public_surface_registry_effect: PreparedPublicSurfaceRegistryEffect,
399
- idempotency_purpose: &str,
400
- ) -> Result<WriteCommand, LixError> {
401
- let semantic_effects =
402
- semantic_plan_effects_from_changes(&changes, context.origin_key.as_deref())?;
403
- let write_payload = json!({
404
- "rows": intended_post_state.iter().map(summarize_planned_row).collect::<Vec<_>>(),
405
- "changes": changes.iter().map(summarize_change).collect::<Vec<_>>(),
406
- "filesystem_files": filesystem_state.files.keys().cloned().collect::<Vec<_>>(),
407
- });
408
- WriteCommand::build(
409
- PreparedWriteStatement {
410
- statement_kind: PreparedWriteStatementKind::Write,
411
- result_contract: ResultContract::DmlNoReturning,
412
- artifact: PreparedWriteArtifact::PublicWrite(PreparedPublicWrite {
413
- contract: PreparedPublicWriteContract {
414
- operation_kind: PreparedWriteOperationKind::Insert,
415
- target,
416
- on_conflict_action: None,
417
- requested_version_id: Some(context.target_version_id().to_string()),
418
- active_account_ids: context.active_account_ids.clone(),
419
- origin_key: context.origin_key.clone(),
420
- resolved_write_plan: Some(PreparedResolvedWritePlan {
421
- partitions: vec![PreparedResolvedWritePartition {
422
- execution_mode: WriteMode::Tracked,
423
- authoritative_pre_state_rows: Vec::new(),
424
- intended_post_state,
425
- filesystem_state,
426
- }],
427
- }),
428
- },
429
- execution: PreparedPublicWritePlanArtifact::Materialize(
430
- PreparedPublicWriteMaterialization {
431
- partitions: vec![PreparedPublicWriteExecution {
432
- execution_mode: WriteMode::Tracked,
433
- intended_post_state: Vec::new(),
434
- schema_live_table_requirements,
435
- change_batch: Some(ChangeBatch {
436
- changes: changes.clone(),
437
- write_lane: WriteLane::GlobalAdmin,
438
- origin_key: context.origin_key.clone(),
439
- semantic_effects: semantic_effect_markers_from_changes(&changes),
440
- }),
441
- create_preconditions: Some(CommitPreconditions {
442
- write_lane: WriteLane::GlobalAdmin,
443
- expected_head: ExpectedHead::CurrentHead,
444
- idempotency_key: semantic_idempotency_key(
445
- idempotency_purpose,
446
- &write_payload,
447
- )?,
448
- }),
449
- semantic_effects,
450
- persist_filesystem_payloads_before_write: false,
451
- }],
452
- },
453
- ),
454
- }),
455
- diagnostic_context: WriteDiagnosticContext::new(vec![relation_name.to_string()]),
456
- public_surface_registry_effect,
457
- },
458
- &context.function_bindings,
459
- )
460
- }
461
-
462
- fn semantic_plan_effects_from_changes(
463
- changes: &[PublicChange],
464
- origin_key: Option<&str>,
465
- ) -> Result<PlanEffects, LixError> {
466
- Ok(PlanEffects {
467
- state_commit_stream_changes: state_commit_stream_changes_from_changes(
468
- changes,
469
- StateCommitStreamOperation::Insert,
470
- StateCommitStreamRuntimeMetadata::from_runtime_origin_key(origin_key),
471
- )?,
472
- ..PlanEffects::default()
473
- })
474
- }
475
-
476
- fn semantic_effect_markers_from_changes(changes: &[PublicChange]) -> Vec<SemanticEffect> {
477
- changes
478
- .iter()
479
- .map(|change| SemanticEffect {
480
- effect_key: "state.upsert".to_string(),
481
- target: format!(
482
- "{}:{}@{}",
483
- change.schema_key, change.entity_id, change.version_id
484
- ),
485
- })
486
- .collect()
487
- }
488
-
489
- fn planned_row_to_public_change(row: &PlannedStateRow) -> Result<PublicChange, LixError> {
490
- Ok(PublicChange {
491
- entity_id: row.entity_id.clone(),
492
- schema_key: row.schema_key.clone(),
493
- file_id: planned_row_text_value(row, "file_id"),
494
- plugin_key: planned_row_text_value(row, "plugin_key"),
495
- snapshot_content: if row.tombstone {
496
- None
497
- } else {
498
- planned_row_json_text_value(row, "snapshot_content")
499
- },
500
- metadata: planned_row_json_text_value(row, "metadata"),
501
- version_id: row
502
- .version_id
503
- .clone()
504
- .or_else(|| planned_row_text_value(row, "version_id"))
505
- .ok_or_else(|| {
506
- LixError::new(
507
- "LIX_ERROR_UNKNOWN",
508
- "semantic tracked write requires a concrete version_id",
509
- )
510
- })?,
511
- origin_key: row.origin_key.clone(),
512
- })
513
- }
514
-
515
- fn planned_row_text_value(row: &PlannedStateRow, key: &str) -> Option<String> {
516
- match row.values.get(key) {
517
- Some(Value::Text(value)) => Some(value.clone()),
518
- Some(Value::Integer(value)) => Some(value.to_string()),
519
- Some(Value::Boolean(value)) => Some(value.to_string()),
520
- Some(Value::Real(value)) => Some(value.to_string()),
521
- _ => None,
522
- }
523
- }
524
-
525
- fn planned_row_json_text_value(row: &PlannedStateRow, key: &str) -> Option<String> {
526
- match row.values.get(key) {
527
- Some(Value::Json(value)) => Some(value.to_string()),
528
- _ => planned_row_text_value(row, key),
529
- }
530
- }
531
-
532
- fn semantic_idempotency_key(
533
- purpose: &str,
534
- payload: &JsonValue,
535
- ) -> Result<IdempotencyKey, LixError> {
536
- let bytes = serde_json::to_vec(payload).map_err(|error| {
537
- LixError::new(
538
- "LIX_ERROR_UNKNOWN",
539
- format!("semantic idempotency payload serialization failed: {error}"),
540
- )
541
- })?;
542
- Ok(IdempotencyKey(
543
- json!({
544
- "purpose": purpose,
545
- "fingerprint": stable_content_fingerprint_hex(&bytes),
546
- })
547
- .to_string(),
548
- ))
549
- }
550
-
551
- fn summarize_change(change: &PublicChange) -> JsonValue {
552
- json!({
553
- "entity_id": change.entity_id,
554
- "schema_key": change.schema_key,
555
- "file_id": change.file_id,
556
- "plugin_key": change.plugin_key,
557
- "version_id": change.version_id,
558
- "origin_key": change.origin_key,
559
- "snapshot_content": change.snapshot_content.as_ref().map(|snapshot| {
560
- stable_content_fingerprint_hex(snapshot.as_bytes())
561
- }),
562
- })
563
- }
564
-
565
- fn summarize_planned_row(row: &PlannedStateRow) -> JsonValue {
566
- json!({
567
- "entity_id": row.entity_id,
568
- "schema_key": row.schema_key,
569
- "version_id": row.version_id,
570
- "tombstone": row.tombstone,
571
- "values": row
572
- .values
573
- .iter()
574
- .map(|(key, value)| {
575
- (
576
- key.clone(),
577
- match value {
578
- Value::Null => json!({ "kind": "null" }),
579
- Value::Text(text) => json!({
580
- "kind": "text",
581
- "sha256": stable_content_fingerprint_hex(text.as_bytes()),
582
- "len": text.len(),
583
- }),
584
- Value::Json(value) => {
585
- let encoded = value.to_string();
586
- json!({
587
- "kind": "json",
588
- "sha256": stable_content_fingerprint_hex(encoded.as_bytes()),
589
- "len": encoded.len(),
590
- })
591
- }
592
- Value::Blob(bytes) => json!({
593
- "kind": "blob",
594
- "sha256": stable_content_fingerprint_hex(bytes),
595
- "len": bytes.len(),
596
- }),
597
- Value::Integer(value) => json!({ "kind": "integer", "value": value }),
598
- Value::Real(value) => json!({ "kind": "real", "value": value }),
599
- Value::Boolean(value) => json!({ "kind": "boolean", "value": value }),
600
- },
601
- )
602
- })
603
- .collect::<serde_json::Map<_, _>>(),
604
- })
605
- }
606
-
607
- fn require_resolved_surface(
608
- public_surface_registry: &SurfaceRegistry,
609
- relation_name: &str,
610
- ) -> Result<ResolvedRelation, LixError> {
611
- public_surface_registry
612
- .bind_relation_name(relation_name)
613
- .ok_or_else(|| {
614
- LixError::new(
615
- "LIX_ERROR_UNKNOWN",
616
- format!("public surface '{relation_name}' is not registered"),
617
- )
618
- })
619
- }