@lix-js/sdk 0.6.0-preview.5 → 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 (274) 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 +38 -207
  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 +38 -71
  16. package/SKILL.md +0 -507
  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 -833
  23. package/dist/engine-wasm/wasm/lix_engine.wasm +0 -0
  24. package/dist/engine-wasm/wasm/lix_engine.wasm.d.ts +0 -27
  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 -359
  29. package/dist-engine-src/README.md +0 -18
  30. package/dist-engine-src/src/backend/capabilities.rs +0 -67
  31. package/dist-engine-src/src/backend/conformance/baseline.rs +0 -1127
  32. package/dist-engine-src/src/backend/conformance/factory.rs +0 -93
  33. package/dist-engine-src/src/backend/conformance/failure_tests.rs +0 -608
  34. package/dist-engine-src/src/backend/conformance/fixtures.rs +0 -26
  35. package/dist-engine-src/src/backend/conformance/mod.rs +0 -75
  36. package/dist-engine-src/src/backend/conformance/model.rs +0 -28
  37. package/dist-engine-src/src/backend/conformance/model_based.rs +0 -257
  38. package/dist-engine-src/src/backend/conformance/persistence.rs +0 -204
  39. package/dist-engine-src/src/backend/conformance/projection.rs +0 -21
  40. package/dist-engine-src/src/backend/conformance/pushdown.rs +0 -24
  41. package/dist-engine-src/src/backend/conformance/runner.rs +0 -90
  42. package/dist-engine-src/src/backend/conformance/scan.rs +0 -24
  43. package/dist-engine-src/src/backend/conformance/write.rs +0 -16
  44. package/dist-engine-src/src/backend/error.rs +0 -94
  45. package/dist-engine-src/src/backend/in_memory.rs +0 -670
  46. package/dist-engine-src/src/backend/mod.rs +0 -39
  47. package/dist-engine-src/src/backend/predicate.rs +0 -80
  48. package/dist-engine-src/src/backend/traits.rs +0 -260
  49. package/dist-engine-src/src/backend/types.rs +0 -239
  50. package/dist-engine-src/src/binary_cas/chunking.rs +0 -31
  51. package/dist-engine-src/src/binary_cas/codec.rs +0 -346
  52. package/dist-engine-src/src/binary_cas/context.rs +0 -139
  53. package/dist-engine-src/src/binary_cas/kv.rs +0 -1038
  54. package/dist-engine-src/src/binary_cas/mod.rs +0 -11
  55. package/dist-engine-src/src/binary_cas/types.rs +0 -121
  56. package/dist-engine-src/src/branch/context.rs +0 -40
  57. package/dist-engine-src/src/branch/lifecycle.rs +0 -221
  58. package/dist-engine-src/src/branch/mod.rs +0 -13
  59. package/dist-engine-src/src/branch/refs.rs +0 -321
  60. package/dist-engine-src/src/branch/stage_rows.rs +0 -67
  61. package/dist-engine-src/src/branch/types.rs +0 -21
  62. package/dist-engine-src/src/catalog/context.rs +0 -412
  63. package/dist-engine-src/src/catalog/mod.rs +0 -10
  64. package/dist-engine-src/src/catalog/schema.rs +0 -4
  65. package/dist-engine-src/src/catalog/snapshot.rs +0 -1114
  66. package/dist-engine-src/src/cel/context.rs +0 -86
  67. package/dist-engine-src/src/cel/error.rs +0 -19
  68. package/dist-engine-src/src/cel/mod.rs +0 -8
  69. package/dist-engine-src/src/cel/provider.rs +0 -9
  70. package/dist-engine-src/src/cel/runtime.rs +0 -167
  71. package/dist-engine-src/src/cel/value.rs +0 -50
  72. package/dist-engine-src/src/changelog/bench_support.rs +0 -785
  73. package/dist-engine-src/src/changelog/change.rs +0 -1
  74. package/dist-engine-src/src/changelog/codec.rs +0 -497
  75. package/dist-engine-src/src/changelog/commit.rs +0 -1
  76. package/dist-engine-src/src/changelog/context.rs +0 -1614
  77. package/dist-engine-src/src/changelog/mod.rs +0 -29
  78. package/dist-engine-src/src/changelog/store.rs +0 -163
  79. package/dist-engine-src/src/changelog/test_support.rs +0 -54
  80. package/dist-engine-src/src/changelog/types.rs +0 -213
  81. package/dist-engine-src/src/commit_graph/context.rs +0 -944
  82. package/dist-engine-src/src/commit_graph/mod.rs +0 -9
  83. package/dist-engine-src/src/commit_graph/types.rs +0 -89
  84. package/dist-engine-src/src/commit_graph/walker.rs +0 -786
  85. package/dist-engine-src/src/common/error.rs +0 -347
  86. package/dist-engine-src/src/common/fingerprint.rs +0 -3
  87. package/dist-engine-src/src/common/fs_path.rs +0 -1336
  88. package/dist-engine-src/src/common/identity.rs +0 -145
  89. package/dist-engine-src/src/common/json_pointer.rs +0 -67
  90. package/dist-engine-src/src/common/metadata.rs +0 -40
  91. package/dist-engine-src/src/common/mod.rs +0 -23
  92. package/dist-engine-src/src/common/types.rs +0 -105
  93. package/dist-engine-src/src/common/wire.rs +0 -222
  94. package/dist-engine-src/src/domain.rs +0 -320
  95. package/dist-engine-src/src/engine.rs +0 -203
  96. package/dist-engine-src/src/entity_pk.rs +0 -402
  97. package/dist-engine-src/src/functions/context.rs +0 -296
  98. package/dist-engine-src/src/functions/deterministic.rs +0 -113
  99. package/dist-engine-src/src/functions/mod.rs +0 -18
  100. package/dist-engine-src/src/functions/provider.rs +0 -130
  101. package/dist-engine-src/src/functions/state.rs +0 -335
  102. package/dist-engine-src/src/functions/types.rs +0 -37
  103. package/dist-engine-src/src/init.rs +0 -692
  104. package/dist-engine-src/src/json_store/compression.rs +0 -77
  105. package/dist-engine-src/src/json_store/context.rs +0 -172
  106. package/dist-engine-src/src/json_store/encoded.rs +0 -15
  107. package/dist-engine-src/src/json_store/mod.rs +0 -38
  108. package/dist-engine-src/src/json_store/store.rs +0 -494
  109. package/dist-engine-src/src/json_store/types.rs +0 -212
  110. package/dist-engine-src/src/lib.rs +0 -92
  111. package/dist-engine-src/src/live_state/context.rs +0 -1883
  112. package/dist-engine-src/src/live_state/mod.rs +0 -21
  113. package/dist-engine-src/src/live_state/overlay.rs +0 -75
  114. package/dist-engine-src/src/live_state/reader.rs +0 -23
  115. package/dist-engine-src/src/live_state/types.rs +0 -231
  116. package/dist-engine-src/src/live_state/visibility.rs +0 -666
  117. package/dist-engine-src/src/plugin/archive.rs +0 -438
  118. package/dist-engine-src/src/plugin/component.rs +0 -183
  119. package/dist-engine-src/src/plugin/install.rs +0 -619
  120. package/dist-engine-src/src/plugin/manifest.rs +0 -516
  121. package/dist-engine-src/src/plugin/materializer.rs +0 -202
  122. package/dist-engine-src/src/plugin/mod.rs +0 -33
  123. package/dist-engine-src/src/plugin/plugin_manifest.json +0 -119
  124. package/dist-engine-src/src/plugin/storage.rs +0 -74
  125. package/dist-engine-src/src/schema/annotations/defaults.rs +0 -275
  126. package/dist-engine-src/src/schema/annotations/mod.rs +0 -1
  127. package/dist-engine-src/src/schema/builtin/lix_account.json +0 -21
  128. package/dist-engine-src/src/schema/builtin/lix_active_account.json +0 -29
  129. package/dist-engine-src/src/schema/builtin/lix_binary_blob_ref.json +0 -29
  130. package/dist-engine-src/src/schema/builtin/lix_branch_descriptor.json +0 -34
  131. package/dist-engine-src/src/schema/builtin/lix_branch_ref.json +0 -48
  132. package/dist-engine-src/src/schema/builtin/lix_change.json +0 -63
  133. package/dist-engine-src/src/schema/builtin/lix_change_author.json +0 -45
  134. package/dist-engine-src/src/schema/builtin/lix_commit.json +0 -24
  135. package/dist-engine-src/src/schema/builtin/lix_commit_edge.json +0 -53
  136. package/dist-engine-src/src/schema/builtin/lix_directory_descriptor.json +0 -52
  137. package/dist-engine-src/src/schema/builtin/lix_file_descriptor.json +0 -52
  138. package/dist-engine-src/src/schema/builtin/lix_key_value.json +0 -40
  139. package/dist-engine-src/src/schema/builtin/lix_label.json +0 -29
  140. package/dist-engine-src/src/schema/builtin/lix_label_assignment.json +0 -74
  141. package/dist-engine-src/src/schema/builtin/lix_registered_schema.json +0 -25
  142. package/dist-engine-src/src/schema/builtin/mod.rs +0 -220
  143. package/dist-engine-src/src/schema/compatibility.rs +0 -787
  144. package/dist-engine-src/src/schema/definition.json +0 -187
  145. package/dist-engine-src/src/schema/definition.rs +0 -742
  146. package/dist-engine-src/src/schema/key.rs +0 -138
  147. package/dist-engine-src/src/schema/mod.rs +0 -20
  148. package/dist-engine-src/src/schema/seed.rs +0 -14
  149. package/dist-engine-src/src/schema/tests.rs +0 -780
  150. package/dist-engine-src/src/session/context.rs +0 -1059
  151. package/dist-engine-src/src/session/create_branch.rs +0 -94
  152. package/dist-engine-src/src/session/execute.rs +0 -681
  153. package/dist-engine-src/src/session/merge/analysis.rs +0 -108
  154. package/dist-engine-src/src/session/merge/branch.rs +0 -417
  155. package/dist-engine-src/src/session/merge/conflicts.rs +0 -63
  156. package/dist-engine-src/src/session/merge/mod.rs +0 -10
  157. package/dist-engine-src/src/session/merge/stats.rs +0 -61
  158. package/dist-engine-src/src/session/mod.rs +0 -30
  159. package/dist-engine-src/src/session/switch_branch.rs +0 -113
  160. package/dist-engine-src/src/session/transaction.rs +0 -557
  161. package/dist-engine-src/src/sql2/bind/classify.rs +0 -102
  162. package/dist-engine-src/src/sql2/bind/error.rs +0 -5
  163. package/dist-engine-src/src/sql2/bind/expr.rs +0 -29
  164. package/dist-engine-src/src/sql2/bind/mod.rs +0 -12
  165. package/dist-engine-src/src/sql2/bind/public_udf.rs +0 -306
  166. package/dist-engine-src/src/sql2/bind/read.rs +0 -65
  167. package/dist-engine-src/src/sql2/bind/statement.rs +0 -2236
  168. package/dist-engine-src/src/sql2/bind/table.rs +0 -273
  169. package/dist-engine-src/src/sql2/bind/write.rs +0 -86
  170. package/dist-engine-src/src/sql2/branch_scope.rs +0 -436
  171. package/dist-engine-src/src/sql2/catalog/capability.rs +0 -20
  172. package/dist-engine-src/src/sql2/catalog/entity_surface.rs +0 -296
  173. package/dist-engine-src/src/sql2/catalog/mod.rs +0 -15
  174. package/dist-engine-src/src/sql2/catalog/registry.rs +0 -556
  175. package/dist-engine-src/src/sql2/catalog/schema.rs +0 -88
  176. package/dist-engine-src/src/sql2/catalog/surface.rs +0 -41
  177. package/dist-engine-src/src/sql2/change_materialization.rs +0 -122
  178. package/dist-engine-src/src/sql2/context.rs +0 -317
  179. package/dist-engine-src/src/sql2/dml.rs +0 -148
  180. package/dist-engine-src/src/sql2/error.rs +0 -215
  181. package/dist-engine-src/src/sql2/exec/bound_public_write.rs +0 -1593
  182. package/dist-engine-src/src/sql2/exec/datafusion.rs +0 -5266
  183. package/dist-engine-src/src/sql2/exec/fast_write.rs +0 -82
  184. package/dist-engine-src/src/sql2/exec/mod.rs +0 -24
  185. package/dist-engine-src/src/sql2/exec/write.rs +0 -661
  186. package/dist-engine-src/src/sql2/filesystem_planner.rs +0 -1485
  187. package/dist-engine-src/src/sql2/filesystem_predicates.rs +0 -159
  188. package/dist-engine-src/src/sql2/filesystem_visibility.rs +0 -383
  189. package/dist-engine-src/src/sql2/history_projection.rs +0 -56
  190. package/dist-engine-src/src/sql2/history_route.rs +0 -661
  191. package/dist-engine-src/src/sql2/mod.rs +0 -52
  192. package/dist-engine-src/src/sql2/optimize/datafusion.rs +0 -1
  193. package/dist-engine-src/src/sql2/optimize/mod.rs +0 -2
  194. package/dist-engine-src/src/sql2/optimize/simple_write.rs +0 -116
  195. package/dist-engine-src/src/sql2/parse/mod.rs +0 -69
  196. package/dist-engine-src/src/sql2/parse/normalize.rs +0 -1
  197. package/dist-engine-src/src/sql2/plan/branch_scope.rs +0 -24
  198. package/dist-engine-src/src/sql2/plan/mod.rs +0 -5
  199. package/dist-engine-src/src/sql2/plan/predicate.rs +0 -22
  200. package/dist-engine-src/src/sql2/plan/write.rs +0 -147
  201. package/dist-engine-src/src/sql2/predicate_typecheck.rs +0 -504
  202. package/dist-engine-src/src/sql2/providers/branch.rs +0 -1206
  203. package/dist-engine-src/src/sql2/providers/change.rs +0 -445
  204. package/dist-engine-src/src/sql2/providers/directory.rs +0 -2422
  205. package/dist-engine-src/src/sql2/providers/directory_history.rs +0 -645
  206. package/dist-engine-src/src/sql2/providers/entity.rs +0 -1484
  207. package/dist-engine-src/src/sql2/providers/entity_history.rs +0 -452
  208. package/dist-engine-src/src/sql2/providers/file.rs +0 -3686
  209. package/dist-engine-src/src/sql2/providers/file_history.rs +0 -924
  210. package/dist-engine-src/src/sql2/providers/history.rs +0 -426
  211. package/dist-engine-src/src/sql2/providers/lix_state.rs +0 -2542
  212. package/dist-engine-src/src/sql2/providers/mod.rs +0 -508
  213. package/dist-engine-src/src/sql2/read_only.rs +0 -63
  214. package/dist-engine-src/src/sql2/record_batch.rs +0 -17
  215. package/dist-engine-src/src/sql2/result_metadata.rs +0 -29
  216. package/dist-engine-src/src/sql2/runtime.rs +0 -60
  217. package/dist-engine-src/src/sql2/session.rs +0 -83
  218. package/dist-engine-src/src/sql2/storage/constraints.rs +0 -1
  219. package/dist-engine-src/src/sql2/storage/mod.rs +0 -1
  220. package/dist-engine-src/src/sql2/test_support/differential.rs +0 -712
  221. package/dist-engine-src/src/sql2/test_support/generators.rs +0 -354
  222. package/dist-engine-src/src/sql2/test_support/mod.rs +0 -2
  223. package/dist-engine-src/src/sql2/udfs/common.rs +0 -295
  224. package/dist-engine-src/src/sql2/udfs/lix_active_branch_commit_id.rs +0 -53
  225. package/dist-engine-src/src/sql2/udfs/lix_empty_blob.rs +0 -47
  226. package/dist-engine-src/src/sql2/udfs/lix_json.rs +0 -100
  227. package/dist-engine-src/src/sql2/udfs/lix_json_get.rs +0 -99
  228. package/dist-engine-src/src/sql2/udfs/lix_json_get_text.rs +0 -99
  229. package/dist-engine-src/src/sql2/udfs/lix_text_decode.rs +0 -82
  230. package/dist-engine-src/src/sql2/udfs/lix_text_encode.rs +0 -85
  231. package/dist-engine-src/src/sql2/udfs/lix_timestamp.rs +0 -76
  232. package/dist-engine-src/src/sql2/udfs/lix_uuid_v7.rs +0 -76
  233. package/dist-engine-src/src/sql2/udfs/mod.rs +0 -86
  234. package/dist-engine-src/src/sql2/write_normalization.rs +0 -368
  235. package/dist-engine-src/src/storage/conformance.rs +0 -399
  236. package/dist-engine-src/src/storage/context.rs +0 -620
  237. package/dist-engine-src/src/storage/mod.rs +0 -52
  238. package/dist-engine-src/src/storage/point.rs +0 -440
  239. package/dist-engine-src/src/storage/read_scope.rs +0 -67
  240. package/dist-engine-src/src/storage/reader.rs +0 -867
  241. package/dist-engine-src/src/storage/scan.rs +0 -784
  242. package/dist-engine-src/src/storage/spaces.rs +0 -236
  243. package/dist-engine-src/src/storage/stats.rs +0 -80
  244. package/dist-engine-src/src/storage/write_set.rs +0 -962
  245. package/dist-engine-src/src/storage_bench.rs +0 -171
  246. package/dist-engine-src/src/test_support.rs +0 -450
  247. package/dist-engine-src/src/tracked_state/bench_support.rs +0 -394
  248. package/dist-engine-src/src/tracked_state/codec.rs +0 -1183
  249. package/dist-engine-src/src/tracked_state/commit_root_rebuild.rs +0 -358
  250. package/dist-engine-src/src/tracked_state/context.rs +0 -2801
  251. package/dist-engine-src/src/tracked_state/diff.rs +0 -2140
  252. package/dist-engine-src/src/tracked_state/merge.rs +0 -478
  253. package/dist-engine-src/src/tracked_state/mod.rs +0 -35
  254. package/dist-engine-src/src/tracked_state/row_materialization.rs +0 -275
  255. package/dist-engine-src/src/tracked_state/storage.rs +0 -427
  256. package/dist-engine-src/src/tracked_state/tree.rs +0 -3063
  257. package/dist-engine-src/src/tracked_state/types.rs +0 -238
  258. package/dist-engine-src/src/transaction/bench_support.rs +0 -407
  259. package/dist-engine-src/src/transaction/commit.rs +0 -1592
  260. package/dist-engine-src/src/transaction/context.rs +0 -1653
  261. package/dist-engine-src/src/transaction/mod.rs +0 -24
  262. package/dist-engine-src/src/transaction/normalization.rs +0 -877
  263. package/dist-engine-src/src/transaction/prep.rs +0 -37
  264. package/dist-engine-src/src/transaction/schema_resolver.rs +0 -163
  265. package/dist-engine-src/src/transaction/staging.rs +0 -1525
  266. package/dist-engine-src/src/transaction/types.rs +0 -403
  267. package/dist-engine-src/src/transaction/validation.rs +0 -5766
  268. package/dist-engine-src/src/untracked_state/codec.rs +0 -615
  269. package/dist-engine-src/src/untracked_state/context.rs +0 -98
  270. package/dist-engine-src/src/untracked_state/materialization.rs +0 -63
  271. package/dist-engine-src/src/untracked_state/mod.rs +0 -15
  272. package/dist-engine-src/src/untracked_state/storage.rs +0 -898
  273. package/dist-engine-src/src/untracked_state/types.rs +0 -146
  274. package/dist-engine-src/src/wasm/mod.rs +0 -60
package/SKILL.md DELETED
@@ -1,507 +0,0 @@
1
- ---
2
- name: lix-js-sdk
3
- description: Use this skill when building examples, demos, tests, or applications with @lix-js/sdk: opening a Lix, registering schemas, writing entities through generated SQL tables, creating named branches, merging, and querying change history.
4
- ---
5
-
6
- # Lix JS SDK Skill
7
-
8
- ## What Is Lix
9
-
10
- Lix is an embeddable branch control system for structured application state. It gives apps named branches, merge, and an immutable SQL-queryable change journal without asking the app to build those systems from scratch.
11
-
12
- Current `@lix-js/sdk` capabilities:
13
-
14
- - Register JSON schemas as tracked entity tables.
15
- - Read and write entities through generated SQL tables.
16
- - Group related writes in explicit transactions so they commit once.
17
- - Create named branches of state and write/read across branches.
18
- - Merge one branch into the active branch.
19
- - Query `lix_change` for history, audit, activity feeds, and undo-style features.
20
- - Store files as bytes with `lix_file` and branch them like other entities.
21
-
22
- Product direction:
23
-
24
- - Lix is designed to track files of any kind by parsing them into typed entities on write.
25
- - Parser plugins that turn file contents into app entities are not shipped through the JS SDK yet. Do not promise this behavior in demos. Today, `lix_file` tracks bytes, while app entities are modeled directly through registered schemas.
26
-
27
- Every row in every registered schema is a tracked entity. Merge granularity is currently per-entity, not per-field: two branches editing different rows merge cleanly; two branches editing the same row conflict, even if the fields are disjoint. Model collaborative domains as many small entities, such as sections, blocks, paragraphs, message keys, or line items.
28
-
29
- Use Lix vocabulary in user-facing copy. Lix uses **branch** for named lines of work.
30
-
31
- ## When To Use This Skill
32
-
33
- Use this skill when you need to write or debug consumer code using `@lix-js/sdk`:
34
-
35
- - Opening a persistent `.lix` file.
36
- - Registering schemas.
37
- - Writing and reading generated SQL entity tables.
38
- - Grouping imports, migrations, and batch writes into one transaction.
39
- - Reading `execute()` results.
40
- - Creating, switching, previewing, and merging branches.
41
- - Querying history through `lix_change`.
42
- - Building app demos, examples, smoke tests, or product flows around the SDK.
43
-
44
- Do not use this skill for raw SQLite access, private engine/wasm internals, SDK publishing, SDK build pipelines, or unreleased file-parser plugin behavior.
45
-
46
- ## Agent Quick Start
47
-
48
- 1. Install `@lix-js/sdk` and `better-sqlite3`.
49
- 2. Open with `createBetterSqlite3Backend({ path })`; do not open `.lix` with raw SQLite.
50
- 3. Register a schema with `x-lix-key`, `x-lix-primary-key`, and `additionalProperties: false`.
51
- 4. Write rows through the generated table named by `x-lix-key`.
52
- 5. Use `beginTransaction()` for imports, migrations, and multi-row writes that should be one commit.
53
- 6. Use `<schema>_by_branch` plus `lixcol_branch_id` for side-by-side branch reads/writes.
54
- 7. Query `lix_change` for audit/history instead of hand-rolling audit tables.
55
- 8. Wrap `mergeBranch()` in `try/catch` whenever conflicts are possible.
56
-
57
- ## Core Rules
58
-
59
- - Use the public `@lix-js/sdk` API only.
60
- - Use `createBetterSqlite3Backend()` for persistent apps, demos, and tests.
61
- - Use numbered SQL placeholders: `$1`, `$2`, `$3`; bare `?` is rejected.
62
- - Use `lix_json($1)` when inserting JSON text into JSON-typed columns.
63
- - Use scalar SQL functions `SELECT lix_uuid_v7()` and `SELECT lix_timestamp()` when consumer code needs Lix-generated UUID v7 ids or ISO timestamps. Do not call them as table functions with `SELECT * FROM ...`.
64
- - Use `beginTransaction()` for batch writes. One `lix.execute()` write is one transaction and therefore one commit.
65
- - Do not call `execute()` through the parent `lix` handle while a transaction is active; use the transaction handle for reads and writes until `commit()` or `rollback()`.
66
- - Use stable, namespaced, lowercase schema keys like `acme_section`, not generic names like `task`.
67
- - Always include `x-lix-primary-key` and `additionalProperties: false` on app schemas.
68
- - Use branch names from the user's vocabulary, such as `"Marketing edit"` or `"Q3 pricing draft"`.
69
- - Model concurrent-edit domains as collections of small rows because merge is per-row today.
70
- - Prefer `_by_branch` tables for demos, sync, agent inspection, and side-by-side diffs.
71
- - Close handles in scripts and tests with `await lix.close()`.
72
-
73
- ## Install And Open
74
-
75
- ```sh
76
- npm i @lix-js/sdk better-sqlite3
77
- ```
78
-
79
- ```ts
80
- import { openLix } from "@lix-js/sdk";
81
- import { createBetterSqlite3Backend } from "@lix-js/sdk/sqlite";
82
-
83
- const lix = await openLix({
84
- backend: createBetterSqlite3Backend({ path: "/path/to/app.lix" }),
85
- });
86
- ```
87
-
88
- `better-sqlite3` is an optional peer dependency. Install it in projects that import `@lix-js/sdk/sqlite`.
89
-
90
- `openLix()` without a backend is in-memory and dies with the process. For anything that should persist, pass a real `.lix` path. Reopening the same path picks up existing state.
91
-
92
- For tests and demos, use an isolated temp directory per run:
93
-
94
- ```ts
95
- import { mkdtempSync } from "node:fs";
96
- import { tmpdir } from "node:os";
97
- import path from "node:path";
98
- import { openLix } from "@lix-js/sdk";
99
- import { createBetterSqlite3Backend } from "@lix-js/sdk/sqlite";
100
-
101
- const dir = mkdtempSync(path.join(tmpdir(), "lix-"));
102
- const lix = await openLix({
103
- backend: createBetterSqlite3Backend({ path: path.join(dir, "demo.lix") }),
104
- });
105
- ```
106
-
107
- Use the version of this skill that ships with the installed `@lix-js/sdk` package. If behavior is unclear, inspect the installed package before guessing. The npm package bundles matching engine source under `node_modules/@lix-js/sdk/dist-engine-src/`.
108
-
109
- Useful installed-package references:
110
-
111
- - `dist-engine-src/src/sql2/providers/entity.rs` - registered schema SQL surfaces.
112
- - `dist-engine-src/src/sql2/providers/change.rs` - `lix_change` projection.
113
- - `dist-engine-src/src/sql2/providers/branch.rs` - writable `lix_branch` surface.
114
- - `dist-engine-src/src/transaction/validation.rs` - primary-key, unique, foreign-key, and shape validation.
115
- - `dist-engine-src/src/schema/definition.json` - Lix schema-definition meta-schema.
116
- - `dist-engine-src/src/schema/builtin/` - built-in entity table shapes.
117
- - `dist-engine-src/src/sql2/udfs/` - registered SQL functions.
118
-
119
- Do not import from `@lix-js/sdk/engine-wasm`, do not call private wasm helpers, and do not open the `.lix` SQLite file directly.
120
-
121
- ## Minimal Entity Example
122
-
123
- This is the smallest useful consumer pattern: open, register a schema, write a row, read it back, and close.
124
-
125
- ```ts
126
- import { mkdtempSync } from "node:fs";
127
- import { tmpdir } from "node:os";
128
- import path from "node:path";
129
- import { openLix } from "@lix-js/sdk";
130
- import { createBetterSqlite3Backend } from "@lix-js/sdk/sqlite";
131
-
132
- const dir = mkdtempSync(path.join(tmpdir(), "lix-"));
133
- const lix = await openLix({
134
- backend: createBetterSqlite3Backend({ path: path.join(dir, "demo.lix") }),
135
- });
136
-
137
- await lix.execute(
138
- "INSERT INTO lix_registered_schema (value) VALUES (lix_json($1))",
139
- [
140
- JSON.stringify({
141
- $schema: "https://json-schema.org/draft/2020-12/schema",
142
- "x-lix-key": "acme_note",
143
- "x-lix-primary-key": ["/id"],
144
- type: "object",
145
- required: ["id", "title", "done"],
146
- properties: {
147
- id: { type: "string" },
148
- title: { type: "string" },
149
- done: { type: "boolean" },
150
- },
151
- additionalProperties: false,
152
- }),
153
- ],
154
- );
155
-
156
- await lix.execute(
157
- "INSERT INTO acme_note (id, title, done) VALUES ($1, $2, $3)",
158
- ["n1", "Draft launch copy", false],
159
- );
160
-
161
- const result = await lix.execute(
162
- "SELECT title, done FROM acme_note WHERE id = $1",
163
- ["n1"],
164
- );
165
-
166
- const row = result.rows[0]!;
167
- console.log(row.value("title").asText(), row.value("done").asBoolean());
168
-
169
- await lix.close();
170
- ```
171
-
172
- ## Reading Results
173
-
174
- `lix.execute()` returns one shape for every statement:
175
-
176
- ```ts
177
- type ExecuteResult = {
178
- columns: string[];
179
- rows: Row[];
180
- rowsAffected: number;
181
- notices: LixNotice[];
182
- };
183
- ```
184
-
185
- There is no `result.kind`. `SELECT` fills `columns` and `rows`; `INSERT`, `UPDATE`, and `DELETE` usually return `rows: []` and set `rowsAffected`.
186
-
187
- Each row is a `Row` object. Use `row.value("column")` or `row.valueAt(index)` to get a `Value`, then call typed accessors:
188
-
189
- ```ts
190
- const r = await lix.execute("SELECT id, title, done FROM acme_note");
191
- for (const row of r.rows) {
192
- const id = row.value("id").asText();
193
- const title = row.value("title").asText();
194
- const done = row.value("done").asBoolean();
195
- }
196
- ```
197
-
198
- | Method | Returns | Use for |
199
- | ------------- | ------------------------- | ----------------------------------------- |
200
- | `asText()` | `string \| undefined` | strings; note `asText`, not `asString` |
201
- | `asBoolean()` | `boolean \| undefined` | booleans |
202
- | `asInteger()` | `number \| undefined` | integer fields |
203
- | `asReal()` | `number \| undefined` | decimal/real fields |
204
- | `asJson()` | `JsonValue \| undefined` | objects and arrays |
205
- | `asBlob()` | `Uint8Array \| undefined` | binary data |
206
-
207
- Accessors return `undefined` when the cell kind does not match. Branch on `value.kind` if a column can hold multiple types. Public kind strings are `"null"`, `"boolean"`, `"integer"`, `"real"`, `"text"`, `"json"`, and `"blob"`.
208
-
209
- `Row` also has convenience methods when native JS values are enough: `get(name)`, `tryGet(name)`, `getAt(index)`, `toObject()`, and `toValueMap()`.
210
-
211
- ## Transactions
212
-
213
- Use `beginTransaction()` whenever several writes belong to one logical operation: CSV imports, seed scripts, migrations, bulk updates, or multi-table changes. A write through `lix.execute()` opens and commits its own transaction, so thousands of separate `execute()` writes become thousands of commits. A transaction handle stages those writes and commits them together.
214
-
215
- ```ts
216
- const tx = await lix.beginTransaction();
217
-
218
- try {
219
- for (const note of notes) {
220
- await tx.execute(
221
- "INSERT INTO acme_note (id, title, done) VALUES ($1, $2, $3)",
222
- [note.id, note.title, false],
223
- );
224
- }
225
-
226
- await tx.commit();
227
- } catch (error) {
228
- await tx.rollback();
229
- throw error;
230
- }
231
- ```
232
-
233
- Transaction rules:
234
-
235
- - `tx.execute()` has the same result shape as `lix.execute()`.
236
- - Writes are visible to later reads on the same transaction before commit.
237
- - `commit()` makes the whole transaction durable as one commit.
238
- - `rollback()` drops the staged writes.
239
- - After `commit()` or `rollback()`, the transaction handle is closed and cannot be reused.
240
- - A Lix handle allows one active transaction at a time. While it is active, use `tx.execute()` for reads and writes; parent-handle `lix.execute()` is rejected until the transaction closes.
241
- - Do not use a callback-style transaction helper. The JS SDK mirrors the Rust SDK shape: explicitly `beginTransaction()`, then `commit()` or `rollback()`.
242
-
243
- ## Registering Schemas
244
-
245
- Register app schemas by inserting JSON into `lix_registered_schema.value`:
246
-
247
- ```ts
248
- await lix.execute(
249
- "INSERT INTO lix_registered_schema (value) VALUES (lix_json($1))",
250
- [JSON.stringify(schema)],
251
- );
252
- ```
253
-
254
- Schema basics:
255
-
256
- - `x-lix-key` becomes the generated SQL table name.
257
- - Compatible schema amendments are keyed by `x-lix-key`.
258
- - `x-lix-primary-key` tells Lix how to derive `entity_pk`.
259
- - Primary-key entries are JSON Pointers with a leading slash, such as `["/id"]` or `["/owner/email"]`.
260
- - Use `additionalProperties: false` so accidental fields fail fast.
261
-
262
- Without `x-lix-primary-key`, table-style INSERTs fail with an error like `requires lixcol_entity_pk because the schema has no x-lix-primary-key`.
263
-
264
- Uniqueness is not inferred from ordinary JSON Schema fields. If a non-primary-key field must be unique, declare it explicitly:
265
-
266
- ```ts
267
- const companyDomainSchema = {
268
- "x-lix-key": "crm_company_domain",
269
- "x-lix-primary-key": ["/id"],
270
- "x-lix-unique": [["/domain"]],
271
- type: "object",
272
- required: ["id", "domain"],
273
- properties: {
274
- id: { type: "string" },
275
- domain: { type: "string" },
276
- },
277
- additionalProperties: false,
278
- };
279
- ```
280
-
281
- Do not add generic `created_at` or `updated_at` fields by default. Lix already records lifecycle history through `lix_change` and `lixcol_*` metadata. Add timestamp fields only when they are domain data, such as `due_at`, `published_at`, or `occurred_at`.
282
-
283
- Discover live schemas before guessing:
284
-
285
- ```ts
286
- const schemas = await lix.execute(
287
- "SELECT lixcol_entity_pk, value FROM lix_registered_schema ORDER BY lixcol_entity_pk",
288
- );
289
-
290
- for (const row of schemas.rows) {
291
- const schema = row.get("value") as { "x-lix-key"?: string };
292
- console.log(schema["x-lix-key"]);
293
- }
294
- ```
295
-
296
- ## Branches And `_by_branch`
297
-
298
- Capture the initial active branch id instead of hardcoding `"main"`:
299
-
300
- ```ts
301
- const published = await lix.activeBranchId();
302
- ```
303
-
304
- Create branches with names from the user's domain:
305
-
306
- ```ts
307
- const marketing = await lix.createBranch({ name: "Marketing edit" });
308
- const legal = await lix.createBranch({ name: "Legal review" });
309
- ```
310
-
311
- Every registered schema `X` gets a sibling table `X_by_branch` with `lixcol_branch_id`. Use it for side-by-side reads and for writes to non-active branches.
312
-
313
- ```ts
314
- await lix.execute(
315
- `UPDATE acme_note_by_branch
316
- SET title = $1
317
- WHERE id = $2 AND lixcol_branch_id = $3`,
318
- ["Sharper launch copy", "n1", marketing.id],
319
- );
320
-
321
- const sideBySide = await lix.execute(
322
- `SELECT v.name, n.title
323
- FROM acme_note_by_branch n
324
- JOIN lix_branch v ON v.id = n.lixcol_branch_id
325
- WHERE n.id = $1
326
- AND n.lixcol_branch_id IN ($2, $3)
327
- ORDER BY v.name`,
328
- ["n1", published, marketing.id],
329
- );
330
- ```
331
-
332
- Rules for `_by_branch`:
333
-
334
- - Reads filter by `lixcol_branch_id`, or omit the filter to scan all branches.
335
- - INSERTs require `lixcol_branch_id`.
336
- - UPDATEs and DELETEs must include `lixcol_branch_id` in the WHERE clause.
337
- - The non-suffixed table is the active-branch view.
338
-
339
- `switchBranch()` is for app code with a current working branch concept. `mergeBranch()` always merges into the active branch, so switch first if you need a different target.
340
-
341
- ## Merging
342
-
343
- `mergeBranch()` merges the source branch into the currently active branch:
344
-
345
- ```ts
346
- try {
347
- const merge = await lix.mergeBranch({ sourceBranchId: marketing.id });
348
- console.log(merge.outcome, merge.changeStats.total);
349
- } catch (error) {
350
- console.error("Merge conflict", error);
351
- }
352
- ```
353
-
354
- Common outcomes:
355
-
356
- - `"alreadyUpToDate"` - source has no commits the target lacks.
357
- - `"fastForward"` - target advanced to source without a merge commit.
358
- - `"mergeCommitted"` - a new merge commit was created.
359
-
360
- `mergeBranchPreview()` reports the same merge decision without advancing refs, staging changes, or creating commits. Merge conflicts are returned as preview data.
361
-
362
- Conflicts throw from `mergeBranch()`. If both branches modified the same entity since their merge base, Lix raises a `LixError`. Conflict detection is row-level today, not field-level. To reproduce a conflict in a demo, fork all contending branches from the same base before merging any of them.
363
-
364
- ## Demo Pattern To Imitate
365
-
366
- For richer demos, show these four things:
367
-
368
- 1. Isolation: one SELECT against `<schema>_by_branch` shows several branches side by side.
369
- 2. Clean parallel merges: two reviewers edit different entities and both land.
370
- 3. Audit history: `lix_change` is queryable SQL.
371
- 4. Conflict handling: two branches edit the same entity and `mergeBranch()` throws.
372
-
373
- Shape the domain as a collection of small entities:
374
-
375
- - Good: brochure sections, document blocks, paragraph rows, message keys, line items.
376
- - Risky: one huge document row with many editable fields.
377
-
378
- Demo recipe:
379
-
380
- 1. Register a schema such as `acme_section`.
381
- 2. Seed several rows in the published branch.
382
- 3. Create all reviewer branches up front from the same base.
383
- 4. Write each reviewer's changes through `acme_section_by_branch`.
384
- 5. Read side by side by joining `acme_section_by_branch` to `lix_branch`.
385
- 6. Merge non-overlapping row edits successfully.
386
- 7. Query `lix_change`.
387
- 8. Catch the deliberate same-row conflict.
388
-
389
- ## Files With `lix_file`
390
-
391
- `lix_file` stores files as branched bytes. Parent directories are created automatically.
392
-
393
- ```ts
394
- await lix.execute("INSERT INTO lix_file (id, path, data, hidden) VALUES ($1, $2, $3, false)", [
395
- "file-readme",
396
- "/docs/readme.md",
397
- new TextEncoder().encode("# Hello\n"),
398
- ]);
399
-
400
- const result = await lix.execute(
401
- "SELECT path, data FROM lix_file WHERE id = $1",
402
- ["file-readme"],
403
- );
404
-
405
- const file = result.rows[0]!;
406
- console.log(
407
- file.value("path").asText(),
408
- new TextDecoder().decode(file.value("data").asBlob()!),
409
- );
410
- ```
411
-
412
- Columns consumers usually need:
413
-
414
- | Column | What it is |
415
- | ---------- | --------------------------------------------------------------------- |
416
- | `id` | Stable identity for the file. |
417
- | `path` | Absolute path like `/docs/readme.md`. |
418
- | `data` | File contents as bytes. |
419
- | `hidden` | UI hint; does not affect storage. |
420
- | `lixcol_*` | Branch/change metadata, including `lixcol_branch_id` where exposed. |
421
-
422
- `lix_file_by_branch` exists for cross-branch file reads and writes. Files-as-parsed-entities are product direction, not current JS SDK behavior.
423
-
424
- ## The Change Journal
425
-
426
- `lix_change` is an immutable SQL table of changes across registered schemas and branches. Use it for audit logs, blame, history, activity feeds, and undo-style UI.
427
-
428
- Important columns include `id`, `entity_pk`, `schema_key`, `snapshot_content`, `created_at`, and `lixcol_*` metadata.
429
-
430
- ```ts
431
- // Audit log for one entity, oldest to newest.
432
- await lix.execute(
433
- `SELECT created_at, snapshot_content
434
- FROM lix_change
435
- WHERE schema_key = $1
436
- AND lix_json_get_text(entity_pk, 0) = $2
437
- ORDER BY created_at`,
438
- ["acme_note", "n1"],
439
- );
440
-
441
- // Latest activity across a schema.
442
- await lix.execute(
443
- `SELECT created_at, entity_pk, snapshot_content
444
- FROM lix_change
445
- WHERE schema_key = $1
446
- ORDER BY created_at DESC
447
- LIMIT 20`,
448
- ["acme_note"],
449
- );
450
- ```
451
-
452
- `snapshot_content` can be null or absent for tombstones, removals, or rows where content was not materialized. In the JS SDK, read it with `row.value("snapshot_content").asJson()` or `row.get("snapshot_content")`, then handle null. Do not blindly `JSON.parse` it as text.
453
-
454
- ## Built-In Tables And UDFs
455
-
456
- Common tables:
457
-
458
- | Table | What it gives consumers |
459
- | ----------------------- | ------------------------------------------------------------------------------------------------------- |
460
- | `lix_branch` | Writable branch surface: `id`, `name`, `hidden`, `commit_id`. |
461
- | `lix_change` | Immutable change journal. |
462
- | `lix_file` | Branched byte storage for files. |
463
- | `lix_registered_schema` | Registry of app schemas plus built-ins; also exposes the Lix schema-definition meta-schema at runtime. |
464
-
465
- `lix_branch` can be updated for admin flows:
466
-
467
- ```ts
468
- await lix.execute("UPDATE lix_branch SET hidden = true WHERE id = $1", [
469
- marketing.id,
470
- ]);
471
- ```
472
-
473
- There is no documented `deleteBranch()` helper in this preview. If the product wants reversible cleanup, hide the branch. If it wants removal, `DELETE FROM lix_branch WHERE id = $1` is the SQL surface; the engine rejects deleting the global branch and active branch.
474
-
475
- Use `lix_json($1)` to parse JSON text parameters when writing JSON-typed columns:
476
-
477
- ```ts
478
- await lix.execute(
479
- "INSERT INTO lix_registered_schema (value) VALUES (lix_json($1))",
480
- [JSON.stringify(schema)],
481
- );
482
- ```
483
-
484
- Other UDFs, such as `lix_json_get`, `lix_uuid_v7`, `lix_text_encode`, and `lix_empty_blob`, live in `dist-engine-src/src/sql2/udfs/` in the installed package.
485
-
486
- ## Do And Avoid
487
-
488
- | Do | Avoid |
489
- | --- | --- |
490
- | Use `createBetterSqlite3Backend({ path })` for persistent state. | Opening `.lix` files with raw SQLite libraries. |
491
- | Use public imports from `@lix-js/sdk` and `@lix-js/sdk/sqlite`. | Importing `engine-wasm` or private internals. |
492
- | Use `$1`, `$2`, `$3` placeholders. | Bare `?` placeholders. |
493
- | Use `lix_json($1)` for JSON parameters. | Inlining stringified JSON directly into SQL. |
494
- | Use `beginTransaction()` for imports and batch writes that should be one commit. | Loops of standalone `lix.execute()` writes for bulk imports. |
495
- | Use the transaction handle for reads and writes until it commits or rolls back. | Calling parent-handle `execute()` during an active transaction. |
496
- | Use `_by_branch` for cross-branch reads/writes. | Switching branches just to render a side-by-side view. |
497
- | Name branches in user vocabulary. | User-facing words like branch, branch-1, or generic Draft. |
498
- | Model collaborative data as small rows. | One giant row when multiple reviewers edit different parts. |
499
- | Add `x-lix-unique` for non-primary unique fields. | Assuming JSON Schema property metadata creates uniqueness. |
500
- | Read `snapshot_content` as JSON/native and handle null. | Blindly `JSON.parse(row.value(...).asText())`. |
501
- | Wrap `mergeBranch()` in `try/catch`. | Assuming merges cannot conflict. |
502
-
503
- ## Reporting SDK Friction
504
-
505
- If you encounter an SDK bug, missing API, confusing error, documentation gap, or large implementation friction while using this skill, pause and ask the user whether they want you to open a GitHub issue via the `gh` CLI installed on their computer. Do not file an issue without confirmation.
506
-
507
- Before filing, scan existing issues to avoid duplicates. If the user approves a report, include a minimal reproduction, expected behavior, actual behavior, the installed `@lix-js/sdk` version, runtime details, and relevant error output. Do not include private data, customer content, credentials, tokens, local paths, database contents, or proprietary schemas.
@@ -1 +0,0 @@
1
- export * from "./generated/builtin-schemas.js";
@@ -1 +0,0 @@
1
- export * from "./generated/builtin-schemas.js";
@@ -1,87 +0,0 @@
1
- export { default } from "./wasm/lix_engine.js";
2
- export * from "./wasm/lix_engine.js";
3
- import type { InitInput } from "./wasm/lix_engine.js";
4
- export type JsonValue = null | boolean | number | string | JsonValue[] | {
5
- [key: string]: JsonValue;
6
- };
7
- export type ValueKind = "null" | "boolean" | "integer" | "real" | "text" | "json" | "blob";
8
- export type LixValue = {
9
- kind: "null";
10
- value: null;
11
- } | {
12
- kind: "boolean";
13
- value: boolean;
14
- } | {
15
- kind: "integer";
16
- value: number;
17
- } | {
18
- kind: "real";
19
- value: number;
20
- } | {
21
- kind: "text";
22
- value: string;
23
- } | {
24
- kind: "json";
25
- value: JsonValue;
26
- } | {
27
- kind: "blob";
28
- base64: string;
29
- };
30
- export declare class Value {
31
- kind: ValueKind;
32
- value: null | boolean | number | string | JsonValue | undefined;
33
- base64: string | undefined;
34
- constructor(kind: ValueKind, value: null | boolean | number | string | JsonValue | undefined, base64?: string);
35
- static null(): Value;
36
- static integer(value: number): Value;
37
- static boolean(value: boolean): Value;
38
- static real(value: number): Value;
39
- static text(value: string): Value;
40
- static json(value: JsonValue): Value;
41
- static blob(value: Uint8Array): Value;
42
- static from(raw: unknown): Value;
43
- asInteger(): number | undefined;
44
- asBoolean(): boolean | undefined;
45
- asReal(): number | undefined;
46
- asText(): string | undefined;
47
- asJson(): JsonValue | undefined;
48
- asBlob(): Uint8Array | undefined;
49
- toJSON(): LixValue;
50
- }
51
- export type ExecuteResult = {
52
- columns: string[];
53
- rows: LixValue[][];
54
- rowsAffected: number;
55
- notices: LixNotice[];
56
- };
57
- export type LixNotice = {
58
- code: string;
59
- message: string;
60
- hint?: string;
61
- };
62
- /**
63
- * Error thrown by the Lix engine. Extends the standard `Error` with a
64
- * machine-readable `code`, optional `hint`, and optional structured `details`.
65
- *
66
- * Hints follow the Postgres/rustc convention: `message` states what went
67
- * wrong in factual terms; `hint` offers a fix when one is known. Consumers
68
- * typically render the hint alongside the primary message (e.g. as
69
- * `hint: <text>` in a CLI, secondary text in a UI).
70
- */
71
- export interface LixError extends Error {
72
- code: string;
73
- hint?: string;
74
- details?: unknown;
75
- }
76
- /**
77
- * Type guard: returns `true` when `err` is a Lix-produced error carrying a
78
- * structured `code` field (all engine codes start with `LIX_`).
79
- */
80
- export declare function isLixError(err: unknown): err is LixError;
81
- /**
82
- * Returns a wasm-bindgen-compatible init input that works in both browser and Node.
83
- *
84
- * - Browser: use a URL so the runtime fetches the `.wasm` asset.
85
- * - Node: read bytes from disk because `fetch(file://...)` is not supported.
86
- */
87
- export declare function resolveEngineWasmModuleOrPath(): Promise<InitInput>;