@lix-js/sdk 0.4.6 → 0.5.0-preview.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 (1106) hide show
  1. package/dist/account/create-account.d.ts +17 -3
  2. package/dist/account/create-account.d.ts.map +1 -1
  3. package/dist/account/create-account.js +27 -3
  4. package/dist/account/create-account.js.map +1 -1
  5. package/dist/account/create-account.test.js +42 -4
  6. package/dist/account/create-account.test.js.map +1 -1
  7. package/dist/account/index.d.ts +1 -1
  8. package/dist/account/index.d.ts.map +1 -1
  9. package/dist/account/index.js +1 -1
  10. package/dist/account/index.js.map +1 -1
  11. package/dist/account/schema.d.ts +28 -0
  12. package/dist/account/schema.d.ts.map +1 -0
  13. package/dist/account/schema.js +55 -0
  14. package/dist/account/schema.js.map +1 -0
  15. package/dist/account/schema.test.d.ts +2 -0
  16. package/dist/account/schema.test.d.ts.map +1 -0
  17. package/dist/account/schema.test.js +306 -0
  18. package/dist/account/schema.test.js.map +1 -0
  19. package/dist/account/switch-account.d.ts +2 -2
  20. package/dist/account/switch-account.d.ts.map +1 -1
  21. package/dist/account/switch-account.js +8 -1
  22. package/dist/account/switch-account.js.map +1 -1
  23. package/dist/account/switch-account.test.js +27 -6
  24. package/dist/account/switch-account.test.js.map +1 -1
  25. package/dist/change/create-change.d.ts +11 -22
  26. package/dist/change/create-change.d.ts.map +1 -1
  27. package/dist/change/create-change.js +29 -83
  28. package/dist/change/create-change.js.map +1 -1
  29. package/dist/change/create-change.test.js +129 -176
  30. package/dist/change/create-change.test.js.map +1 -1
  31. package/dist/change/index.d.ts +1 -2
  32. package/dist/change/index.d.ts.map +1 -1
  33. package/dist/change/index.js +1 -2
  34. package/dist/change/index.js.map +1 -1
  35. package/dist/change/mock-change.d.ts +1 -1
  36. package/dist/change/mock-change.d.ts.map +1 -1
  37. package/dist/change/mock-change.js +1 -0
  38. package/dist/change/mock-change.js.map +1 -1
  39. package/dist/change/schema.d.ts +28 -0
  40. package/dist/change/schema.d.ts.map +1 -0
  41. package/dist/change/schema.js +62 -0
  42. package/dist/change/schema.js.map +1 -0
  43. package/dist/change/schema.test.d.ts +2 -0
  44. package/dist/change/schema.test.d.ts.map +1 -0
  45. package/dist/change/schema.test.js +235 -0
  46. package/dist/change/schema.test.js.map +1 -0
  47. package/dist/change-author/index.d.ts +2 -0
  48. package/dist/change-author/index.d.ts.map +1 -0
  49. package/dist/change-author/index.js +2 -0
  50. package/dist/change-author/index.js.map +1 -0
  51. package/dist/change-author/schema.d.ts +31 -0
  52. package/dist/change-author/schema.d.ts.map +1 -0
  53. package/dist/change-author/schema.js +35 -0
  54. package/dist/change-author/schema.js.map +1 -0
  55. package/dist/change-author/schema.test.d.ts +2 -0
  56. package/dist/change-author/schema.test.d.ts.map +1 -0
  57. package/dist/change-author/schema.test.js +256 -0
  58. package/dist/change-author/schema.test.js.map +1 -0
  59. package/dist/change-conflict/create-change-conflict.d.ts.map +1 -1
  60. package/dist/change-conflict/create-change-conflict.js +24 -6
  61. package/dist/change-conflict/create-change-conflict.js.map +1 -1
  62. package/dist/change-conflict/create-change-conflict.test.js +13 -11
  63. package/dist/change-conflict/create-change-conflict.test.js.map +1 -1
  64. package/dist/change-conflict/detect-change-conflicts.d.ts.map +1 -1
  65. package/dist/change-conflict/detect-change-conflicts.js +2 -0
  66. package/dist/change-conflict/detect-change-conflicts.js.map +1 -1
  67. package/dist/change-conflict/detect-change-conflicts.test.js +17 -13
  68. package/dist/change-conflict/detect-change-conflicts.test.js.map +1 -1
  69. package/dist/change-conflict/detect-diverging-entity-conflict.d.ts.map +1 -1
  70. package/dist/change-conflict/detect-diverging-entity-conflict.js +3 -1
  71. package/dist/change-conflict/detect-diverging-entity-conflict.js.map +1 -1
  72. package/dist/change-conflict/detect-diverging-entity-conflict.test.js +23 -21
  73. package/dist/change-conflict/detect-diverging-entity-conflict.test.js.map +1 -1
  74. package/dist/change-conflict/garbage-collect-change-conflicts.d.ts.map +1 -1
  75. package/dist/change-conflict/garbage-collect-change-conflicts.js +2 -0
  76. package/dist/change-conflict/garbage-collect-change-conflicts.js.map +1 -1
  77. package/dist/change-conflict/garbage-collect-change-conflicts.test.js +15 -15
  78. package/dist/change-conflict/garbage-collect-change-conflicts.test.js.map +1 -1
  79. package/dist/change-conflict/resolve-conflict-by-selecting.d.ts.map +1 -1
  80. package/dist/change-conflict/resolve-conflict-by-selecting.js +2 -2
  81. package/dist/change-conflict/resolve-conflict-by-selecting.js.map +1 -1
  82. package/dist/change-conflict/resolve-conflict-by-selecting.test.js +17 -8
  83. package/dist/change-conflict/resolve-conflict-by-selecting.test.js.map +1 -1
  84. package/dist/change-proposal/create-change-proposal.d.ts +16 -0
  85. package/dist/change-proposal/create-change-proposal.d.ts.map +1 -0
  86. package/dist/change-proposal/create-change-proposal.js +52 -0
  87. package/dist/change-proposal/create-change-proposal.js.map +1 -0
  88. package/dist/change-proposal/create-change-proposal.test.d.ts +2 -0
  89. package/dist/change-proposal/create-change-proposal.test.d.ts.map +1 -0
  90. package/dist/change-proposal/create-change-proposal.test.js +91 -0
  91. package/dist/change-proposal/create-change-proposal.test.js.map +1 -0
  92. package/dist/change-proposal/database-schema.d.ts +13 -0
  93. package/dist/change-proposal/database-schema.d.ts.map +1 -0
  94. package/dist/change-proposal/database-schema.js +17 -0
  95. package/dist/change-proposal/database-schema.js.map +1 -0
  96. package/dist/change-proposal/database-schema.test.d.ts +2 -0
  97. package/dist/change-proposal/database-schema.test.d.ts.map +1 -0
  98. package/dist/change-proposal/database-schema.test.js +159 -0
  99. package/dist/change-proposal/database-schema.test.js.map +1 -0
  100. package/dist/change-proposal/index.d.ts +3 -0
  101. package/dist/change-proposal/index.d.ts.map +1 -0
  102. package/dist/change-proposal/index.js +3 -0
  103. package/dist/change-proposal/index.js.map +1 -0
  104. package/dist/change-set/apply-change-set.d.ts +10 -0
  105. package/dist/change-set/apply-change-set.d.ts.map +1 -0
  106. package/dist/change-set/apply-change-set.js +150 -0
  107. package/dist/change-set/apply-change-set.js.map +1 -0
  108. package/dist/change-set/apply-change-set.test.d.ts +2 -0
  109. package/dist/change-set/apply-change-set.test.d.ts.map +1 -0
  110. package/dist/change-set/apply-change-set.test.js +390 -0
  111. package/dist/change-set/apply-change-set.test.js.map +1 -0
  112. package/dist/change-set/change-set-element-in-symmetric-difference.d.ts.map +1 -1
  113. package/dist/change-set/create-change-set.d.ts +19 -18
  114. package/dist/change-set/create-change-set.d.ts.map +1 -1
  115. package/dist/change-set/create-change-set.js +95 -34
  116. package/dist/change-set/create-change-set.js.map +1 -1
  117. package/dist/change-set/create-change-set.test.js +109 -27
  118. package/dist/change-set/create-change-set.test.js.map +1 -1
  119. package/dist/change-set/create-checkpoint.d.ts +19 -0
  120. package/dist/change-set/create-checkpoint.d.ts.map +1 -0
  121. package/dist/change-set/create-checkpoint.js +86 -0
  122. package/dist/change-set/create-checkpoint.js.map +1 -0
  123. package/dist/change-set/create-checkpoint.test.d.ts +2 -0
  124. package/dist/change-set/create-checkpoint.test.d.ts.map +1 -0
  125. package/dist/change-set/create-checkpoint.test.js +294 -0
  126. package/dist/change-set/create-checkpoint.test.js.map +1 -0
  127. package/dist/change-set/create-merge-change-set.d.ts +23 -0
  128. package/dist/change-set/create-merge-change-set.d.ts.map +1 -0
  129. package/dist/change-set/create-merge-change-set.js +68 -0
  130. package/dist/change-set/create-merge-change-set.js.map +1 -0
  131. package/dist/change-set/create-merge-change-set.test.d.ts +2 -0
  132. package/dist/change-set/create-merge-change-set.test.d.ts.map +1 -0
  133. package/dist/change-set/create-merge-change-set.test.js +211 -0
  134. package/dist/change-set/create-merge-change-set.test.js.map +1 -0
  135. package/dist/change-set/create-transition-change-set.d.ts +18 -0
  136. package/dist/change-set/create-transition-change-set.d.ts.map +1 -0
  137. package/dist/change-set/create-transition-change-set.js +102 -0
  138. package/dist/change-set/create-transition-change-set.js.map +1 -0
  139. package/dist/change-set/create-transition-change-set.test.d.ts +2 -0
  140. package/dist/change-set/create-transition-change-set.test.d.ts.map +1 -0
  141. package/dist/change-set/create-transition-change-set.test.js +211 -0
  142. package/dist/change-set/create-transition-change-set.test.js.map +1 -0
  143. package/dist/change-set/create-undo-change-set.d.ts +27 -0
  144. package/dist/change-set/create-undo-change-set.d.ts.map +1 -0
  145. package/dist/change-set/create-undo-change-set.js +121 -0
  146. package/dist/change-set/create-undo-change-set.js.map +1 -0
  147. package/dist/change-set/create-undo-change-set.test.d.ts +2 -0
  148. package/dist/change-set/create-undo-change-set.test.d.ts.map +1 -0
  149. package/dist/change-set/create-undo-change-set.test.js +273 -0
  150. package/dist/change-set/create-undo-change-set.test.js.map +1 -0
  151. package/dist/change-set/index.d.ts +6 -1
  152. package/dist/change-set/index.d.ts.map +1 -1
  153. package/dist/change-set/index.js +6 -1
  154. package/dist/change-set/index.js.map +1 -1
  155. package/dist/change-set/schema.d.ts +149 -0
  156. package/dist/change-set/schema.d.ts.map +1 -0
  157. package/dist/change-set/schema.js +169 -0
  158. package/dist/change-set/schema.js.map +1 -0
  159. package/dist/change-set/schema.test.d.ts +2 -0
  160. package/dist/change-set/schema.test.d.ts.map +1 -0
  161. package/dist/change-set/schema.test.js +821 -0
  162. package/dist/change-set/schema.test.js.map +1 -0
  163. package/dist/database/execute-sync.d.ts +12 -6
  164. package/dist/database/execute-sync.d.ts.map +1 -1
  165. package/dist/database/execute-sync.js +25 -24
  166. package/dist/database/execute-sync.js.map +1 -1
  167. package/dist/database/execute-sync.test.js +53 -60
  168. package/dist/database/execute-sync.test.js.map +1 -1
  169. package/dist/database/graph-traversal-mode.d.ts +72 -0
  170. package/dist/database/graph-traversal-mode.d.ts.map +1 -0
  171. package/dist/database/graph-traversal-mode.js +2 -0
  172. package/dist/database/graph-traversal-mode.js.map +1 -0
  173. package/dist/database/index.d.ts +3 -2
  174. package/dist/database/index.d.ts.map +1 -1
  175. package/dist/database/index.js +3 -2
  176. package/dist/database/index.js.map +1 -1
  177. package/dist/database/init-db.d.ts +2 -0
  178. package/dist/database/init-db.d.ts.map +1 -1
  179. package/dist/database/init-db.js +69 -56
  180. package/dist/database/init-db.js.map +1 -1
  181. package/dist/database/kysely-plugin/json-column-plugin.d.ts +3 -0
  182. package/dist/database/kysely-plugin/json-column-plugin.d.ts.map +1 -0
  183. package/dist/database/kysely-plugin/json-column-plugin.js +168 -0
  184. package/dist/database/kysely-plugin/json-column-plugin.js.map +1 -0
  185. package/dist/database/kysely-plugin/parse-jsonb-plugin-v1.d.ts.map +1 -1
  186. package/dist/database/kysely-plugin/parse-jsonb-plugin-v1.js +5 -10
  187. package/dist/database/kysely-plugin/parse-jsonb-plugin-v1.js.map +1 -1
  188. package/dist/database/kysely-plugin/parse-jsonb-plugin-v2.js +1 -1
  189. package/dist/database/kysely-plugin/parse-jsonb-plugin-v2.js.map +1 -1
  190. package/dist/database/kysely-plugin/serialize-jsonb-plugin.d.ts +14 -2
  191. package/dist/database/kysely-plugin/serialize-jsonb-plugin.d.ts.map +1 -1
  192. package/dist/database/kysely-plugin/serialize-jsonb-plugin.js +145 -74
  193. package/dist/database/kysely-plugin/serialize-jsonb-plugin.js.map +1 -1
  194. package/dist/database/kysely-plugin/serialize-jsonb-plugin.test.js +145 -1
  195. package/dist/database/kysely-plugin/serialize-jsonb-plugin.test.js.map +1 -1
  196. package/dist/database/kysely-plugin/view-insert-returning-error-plugin.d.ts +15 -0
  197. package/dist/database/kysely-plugin/view-insert-returning-error-plugin.d.ts.map +1 -0
  198. package/dist/database/kysely-plugin/view-insert-returning-error-plugin.js +31 -0
  199. package/dist/database/kysely-plugin/view-insert-returning-error-plugin.js.map +1 -0
  200. package/dist/database/kysely-plugin/view-insert-returning-error-plugin.test.d.ts +2 -0
  201. package/dist/database/kysely-plugin/view-insert-returning-error-plugin.test.d.ts.map +1 -0
  202. package/dist/database/kysely-plugin/view-insert-returning-error-plugin.test.js +51 -0
  203. package/dist/database/kysely-plugin/view-insert-returning-error-plugin.test.js.map +1 -0
  204. package/dist/database/schema.d.ts +42 -208
  205. package/dist/database/schema.d.ts.map +1 -1
  206. package/dist/database/schema.js +35 -1
  207. package/dist/database/schema.js.map +1 -1
  208. package/dist/entity-views/entity-state-all.d.ts +217 -0
  209. package/dist/entity-views/entity-state-all.d.ts.map +1 -0
  210. package/dist/entity-views/entity-state-all.js +246 -0
  211. package/dist/entity-views/entity-state-all.js.map +1 -0
  212. package/dist/entity-views/entity-state-all.test.d.ts +2 -0
  213. package/dist/entity-views/entity-state-all.test.d.ts.map +1 -0
  214. package/dist/entity-views/entity-state-all.test.js +371 -0
  215. package/dist/entity-views/entity-state-all.test.js.map +1 -0
  216. package/dist/entity-views/entity-state-history.d.ts +178 -0
  217. package/dist/entity-views/entity-state-history.d.ts.map +1 -0
  218. package/dist/entity-views/entity-state-history.js +58 -0
  219. package/dist/entity-views/entity-state-history.js.map +1 -0
  220. package/dist/entity-views/entity-state-history.test.d.ts +2 -0
  221. package/dist/entity-views/entity-state-history.test.d.ts.map +1 -0
  222. package/dist/entity-views/entity-state-history.test.js +274 -0
  223. package/dist/entity-views/entity-state-history.test.js.map +1 -0
  224. package/dist/entity-views/entity-state.d.ts +217 -0
  225. package/dist/entity-views/entity-state.d.ts.map +1 -0
  226. package/dist/entity-views/entity-state.js +243 -0
  227. package/dist/entity-views/entity-state.js.map +1 -0
  228. package/dist/entity-views/entity-state.test.d.ts +2 -0
  229. package/dist/entity-views/entity-state.test.d.ts.map +1 -0
  230. package/dist/entity-views/entity-state.test.js +497 -0
  231. package/dist/entity-views/entity-state.test.js.map +1 -0
  232. package/dist/entity-views/entity-state_history.d.ts +67 -0
  233. package/dist/entity-views/entity-state_history.d.ts.map +1 -0
  234. package/dist/entity-views/entity-state_history.js +58 -0
  235. package/dist/entity-views/entity-state_history.js.map +1 -0
  236. package/dist/entity-views/entity-view-builder.d.ts +92 -0
  237. package/dist/entity-views/entity-view-builder.d.ts.map +1 -0
  238. package/dist/entity-views/entity-view-builder.js +63 -0
  239. package/dist/entity-views/entity-view-builder.js.map +1 -0
  240. package/dist/entity-views/entity-view-builder.test.d.ts +2 -0
  241. package/dist/entity-views/entity-view-builder.test.d.ts.map +1 -0
  242. package/dist/entity-views/entity-view-builder.test.js +247 -0
  243. package/dist/entity-views/entity-view-builder.test.js.map +1 -0
  244. package/dist/entity-views/generic-types.d.ts +128 -0
  245. package/dist/entity-views/generic-types.d.ts.map +1 -0
  246. package/dist/entity-views/generic-types.js +2 -0
  247. package/dist/entity-views/generic-types.js.map +1 -0
  248. package/dist/entity-views/generic-types.test.d.ts +2 -0
  249. package/dist/entity-views/generic-types.test.d.ts.map +1 -0
  250. package/dist/entity-views/generic-types.test.js +99 -0
  251. package/dist/entity-views/generic-types.test.js.map +1 -0
  252. package/dist/entity-views/index.d.ts +2 -0
  253. package/dist/entity-views/index.d.ts.map +1 -0
  254. package/dist/entity-views/index.js +2 -0
  255. package/dist/entity-views/index.js.map +1 -0
  256. package/dist/entity-views/types.d.ts +309 -0
  257. package/dist/entity-views/types.d.ts.map +1 -0
  258. package/dist/entity-views/types.js +2 -0
  259. package/dist/entity-views/types.js.map +1 -0
  260. package/dist/entity-views/types.test.d.ts +2 -0
  261. package/dist/entity-views/types.test.d.ts.map +1 -0
  262. package/dist/entity-views/types.test.js +62 -0
  263. package/dist/entity-views/types.test.js.map +1 -0
  264. package/dist/file/file-handlers.d.ts +15 -0
  265. package/dist/file/file-handlers.d.ts.map +1 -0
  266. package/dist/file/file-handlers.js +318 -0
  267. package/dist/file/file-handlers.js.map +1 -0
  268. package/dist/file/file-handlers.test.d.ts +2 -0
  269. package/dist/file/file-handlers.test.d.ts.map +1 -0
  270. package/dist/file/file-handlers.test.js +151 -0
  271. package/dist/file/file-handlers.test.js.map +1 -0
  272. package/dist/file/index.d.ts +1 -1
  273. package/dist/file/index.d.ts.map +1 -1
  274. package/dist/file/index.js +1 -1
  275. package/dist/file/index.js.map +1 -1
  276. package/dist/file/materialize-file-data-at-changeset.d.ts +9 -0
  277. package/dist/file/materialize-file-data-at-changeset.d.ts.map +1 -0
  278. package/dist/file/materialize-file-data-at-changeset.js +93 -0
  279. package/dist/file/materialize-file-data-at-changeset.js.map +1 -0
  280. package/dist/file/materialize-file-data.d.ts +8 -0
  281. package/dist/file/materialize-file-data.d.ts.map +1 -0
  282. package/dist/file/materialize-file-data.js +91 -0
  283. package/dist/file/materialize-file-data.js.map +1 -0
  284. package/dist/file/materialize-file-data.test.d.ts +2 -0
  285. package/dist/file/materialize-file-data.test.d.ts.map +1 -0
  286. package/dist/file/materialize-file-data.test.js +90 -0
  287. package/dist/file/materialize-file-data.test.js.map +1 -0
  288. package/dist/file/schema.d.ts +46 -0
  289. package/dist/file/schema.d.ts.map +1 -0
  290. package/dist/file/schema.js +265 -0
  291. package/dist/file/schema.js.map +1 -0
  292. package/dist/file/schema.test.d.ts +2 -0
  293. package/dist/file/schema.test.d.ts.map +1 -0
  294. package/dist/file/schema.test.js +805 -0
  295. package/dist/file/schema.test.js.map +1 -0
  296. package/dist/file/store-detected-change-schema.d.ts +8 -0
  297. package/dist/file/store-detected-change-schema.d.ts.map +1 -0
  298. package/dist/file/store-detected-change-schema.js +41 -0
  299. package/dist/file/store-detected-change-schema.js.map +1 -0
  300. package/dist/file/store-detected-change-schema.test.d.ts +2 -0
  301. package/dist/file/store-detected-change-schema.test.d.ts.map +1 -0
  302. package/dist/file/store-detected-change-schema.test.js +211 -0
  303. package/dist/file/store-detected-change-schema.test.js.map +1 -0
  304. package/dist/file/unknown-file-fallback-plugin.d.ts +22 -0
  305. package/dist/file/unknown-file-fallback-plugin.d.ts.map +1 -0
  306. package/dist/file/unknown-file-fallback-plugin.js +73 -0
  307. package/dist/file/unknown-file-fallback-plugin.js.map +1 -0
  308. package/dist/file/unknown-file-fallback-plugin.test.d.ts +2 -0
  309. package/dist/file/unknown-file-fallback-plugin.test.d.ts.map +1 -0
  310. package/dist/file/unknown-file-fallback-plugin.test.js +305 -0
  311. package/dist/file/unknown-file-fallback-plugin.test.js.map +1 -0
  312. package/dist/hooks/create-hooks.d.ts +72 -0
  313. package/dist/hooks/create-hooks.d.ts.map +1 -0
  314. package/dist/hooks/create-hooks.js +29 -0
  315. package/dist/hooks/create-hooks.js.map +1 -0
  316. package/dist/hooks/create-hooks.test.d.ts +2 -0
  317. package/dist/hooks/create-hooks.test.d.ts.map +1 -0
  318. package/dist/hooks/create-hooks.test.js +98 -0
  319. package/dist/hooks/create-hooks.test.js.map +1 -0
  320. package/dist/hooks/index.d.ts +2 -0
  321. package/dist/hooks/index.d.ts.map +1 -0
  322. package/dist/hooks/index.js +2 -0
  323. package/dist/hooks/index.js.map +1 -0
  324. package/dist/index.d.ts +10 -6
  325. package/dist/index.d.ts.map +1 -1
  326. package/dist/index.js +10 -6
  327. package/dist/index.js.map +1 -1
  328. package/dist/key-value/index.d.ts +2 -0
  329. package/dist/key-value/index.d.ts.map +1 -0
  330. package/dist/key-value/index.js +2 -0
  331. package/dist/key-value/index.js.map +1 -0
  332. package/dist/key-value/schema.d.ts +21 -0
  333. package/dist/key-value/schema.d.ts.map +1 -0
  334. package/dist/key-value/schema.js +25 -0
  335. package/dist/key-value/schema.js.map +1 -0
  336. package/dist/key-value/schema.test.d.ts +2 -0
  337. package/dist/key-value/schema.test.d.ts.map +1 -0
  338. package/dist/key-value/schema.test.js +148 -0
  339. package/dist/key-value/schema.test.js.map +1 -0
  340. package/dist/label/create-label.d.ts +20 -0
  341. package/dist/label/create-label.d.ts.map +1 -0
  342. package/dist/label/create-label.js +45 -0
  343. package/dist/label/create-label.js.map +1 -0
  344. package/dist/label/create-label.test.d.ts +2 -0
  345. package/dist/label/create-label.test.d.ts.map +1 -0
  346. package/dist/label/create-label.test.js +191 -0
  347. package/dist/label/create-label.test.js.map +1 -0
  348. package/dist/label/index.d.ts +3 -0
  349. package/dist/label/index.d.ts.map +1 -0
  350. package/dist/label/index.js +3 -0
  351. package/dist/label/index.js.map +1 -0
  352. package/dist/label/schema.d.ts +22 -0
  353. package/dist/label/schema.d.ts.map +1 -0
  354. package/dist/label/schema.js +28 -0
  355. package/dist/label/schema.js.map +1 -0
  356. package/dist/label/schema.test.d.ts +2 -0
  357. package/dist/label/schema.test.d.ts.map +1 -0
  358. package/dist/label/schema.test.js +76 -0
  359. package/dist/label/schema.test.js.map +1 -0
  360. package/dist/lix/close-lix.d.ts +10 -1
  361. package/dist/lix/close-lix.d.ts.map +1 -1
  362. package/dist/lix/close-lix.js +10 -1
  363. package/dist/lix/close-lix.js.map +1 -1
  364. package/dist/lix/index.d.ts +3 -2
  365. package/dist/lix/index.d.ts.map +1 -1
  366. package/dist/lix/index.js +3 -5
  367. package/dist/lix/index.js.map +1 -1
  368. package/dist/lix/new-lix.d.ts +77 -4
  369. package/dist/lix/new-lix.d.ts.map +1 -1
  370. package/dist/lix/new-lix.js +303 -8
  371. package/dist/lix/new-lix.js.map +1 -1
  372. package/dist/lix/new-lix.test.js +171 -16
  373. package/dist/lix/new-lix.test.js.map +1 -1
  374. package/dist/lix/open-lix-in-memory.d.ts +9 -1
  375. package/dist/lix/open-lix-in-memory.d.ts.map +1 -1
  376. package/dist/lix/open-lix-in-memory.js +15 -7
  377. package/dist/lix/open-lix-in-memory.js.map +1 -1
  378. package/dist/lix/open-lix-in-memory.test.js +0 -6
  379. package/dist/lix/open-lix-in-memory.test.js.map +1 -1
  380. package/dist/lix/open-lix.d.ts +68 -6
  381. package/dist/lix/open-lix.d.ts.map +1 -1
  382. package/dist/lix/open-lix.js +80 -14
  383. package/dist/lix/open-lix.js.map +1 -1
  384. package/dist/lix/open-lix.test.js +54 -22
  385. package/dist/lix/open-lix.test.js.map +1 -1
  386. package/dist/lix/storage/in-memory.d.ts +34 -0
  387. package/dist/lix/storage/in-memory.d.ts.map +1 -0
  388. package/dist/lix/storage/in-memory.js +57 -0
  389. package/dist/lix/storage/in-memory.js.map +1 -0
  390. package/dist/lix/storage/in-memory.test.d.ts +2 -0
  391. package/dist/lix/storage/in-memory.test.d.ts.map +1 -0
  392. package/dist/lix/storage/in-memory.test.js +146 -0
  393. package/dist/lix/storage/in-memory.test.js.map +1 -0
  394. package/dist/lix/storage/lix-storage-adapter.d.ts +16 -0
  395. package/dist/lix/storage/lix-storage-adapter.d.ts.map +1 -0
  396. package/dist/lix/storage/lix-storage-adapter.js +2 -0
  397. package/dist/lix/storage/lix-storage-adapter.js.map +1 -0
  398. package/dist/lix/storage/opfs.d.ts +66 -0
  399. package/dist/lix/storage/opfs.d.ts.map +1 -0
  400. package/dist/lix/storage/opfs.js +152 -0
  401. package/dist/lix/storage/opfs.js.map +1 -0
  402. package/dist/lix/storage/opfs.test.d.ts +2 -0
  403. package/dist/lix/storage/opfs.test.d.ts.map +1 -0
  404. package/dist/lix/storage/opfs.test.js +171 -0
  405. package/dist/lix/storage/opfs.test.js.map +1 -0
  406. package/dist/lix/to-blob.d.ts +9 -2
  407. package/dist/lix/to-blob.d.ts.map +1 -1
  408. package/dist/lix/to-blob.js +9 -2
  409. package/dist/lix/to-blob.js.map +1 -1
  410. package/dist/lix/to-blob.test.d.ts +2 -0
  411. package/dist/lix/to-blob.test.d.ts.map +1 -0
  412. package/dist/lix/to-blob.test.js +18 -0
  413. package/dist/lix/to-blob.test.js.map +1 -0
  414. package/dist/log/create-lix-own-log.d.ts +66 -0
  415. package/dist/log/create-lix-own-log.d.ts.map +1 -0
  416. package/dist/log/create-lix-own-log.js +103 -0
  417. package/dist/log/create-lix-own-log.js.map +1 -0
  418. package/dist/log/create-lix-own-log.test.d.ts +2 -0
  419. package/dist/log/create-lix-own-log.test.d.ts.map +1 -0
  420. package/dist/log/create-lix-own-log.test.js +81 -0
  421. package/dist/log/create-lix-own-log.test.js.map +1 -0
  422. package/dist/log/create-log.d.ts +32 -0
  423. package/dist/log/create-log.d.ts.map +1 -0
  424. package/dist/log/create-log.js +43 -0
  425. package/dist/log/create-log.js.map +1 -0
  426. package/dist/log/index.d.ts +3 -0
  427. package/dist/log/index.d.ts.map +1 -0
  428. package/dist/log/index.js +3 -0
  429. package/dist/log/index.js.map +1 -0
  430. package/dist/log/schema.d.ts +32 -0
  431. package/dist/log/schema.d.ts.map +1 -0
  432. package/dist/log/schema.js +43 -0
  433. package/dist/log/schema.js.map +1 -0
  434. package/dist/log/schema.test.d.ts +2 -0
  435. package/dist/log/schema.test.d.ts.map +1 -0
  436. package/dist/log/schema.test.js +119 -0
  437. package/dist/log/schema.test.js.map +1 -0
  438. package/dist/observe/create-observe.d.ts +17 -0
  439. package/dist/observe/create-observe.d.ts.map +1 -0
  440. package/dist/observe/create-observe.js +118 -0
  441. package/dist/observe/create-observe.js.map +1 -0
  442. package/dist/observe/create-observe.test.d.ts +2 -0
  443. package/dist/observe/create-observe.test.d.ts.map +1 -0
  444. package/dist/observe/create-observe.test.js +384 -0
  445. package/dist/observe/create-observe.test.js.map +1 -0
  446. package/dist/observe/index.d.ts +2 -0
  447. package/dist/observe/index.d.ts.map +1 -0
  448. package/dist/observe/index.js +2 -0
  449. package/dist/observe/index.js.map +1 -0
  450. package/dist/observe/lix-observable.d.ts +31 -0
  451. package/dist/observe/lix-observable.d.ts.map +1 -0
  452. package/dist/observe/lix-observable.js +65 -0
  453. package/dist/observe/lix-observable.js.map +1 -0
  454. package/dist/observe/lix-observable.test.d.ts +2 -0
  455. package/dist/observe/lix-observable.test.d.ts.map +1 -0
  456. package/dist/observe/lix-observable.test.js +187 -0
  457. package/dist/observe/lix-observable.test.js.map +1 -0
  458. package/dist/plugin/index.d.ts +2 -1
  459. package/dist/plugin/index.d.ts.map +1 -1
  460. package/dist/plugin/index.js +1 -1
  461. package/dist/plugin/index.js.map +1 -1
  462. package/dist/plugin/lix-plugin.d.ts +24 -45
  463. package/dist/plugin/lix-plugin.d.ts.map +1 -1
  464. package/dist/plugin/lix-plugin.js +1 -1
  465. package/dist/plugin/lix-plugin.js.map +1 -1
  466. package/dist/plugin/lix-plugin.test-d.js +17 -11
  467. package/dist/plugin/lix-plugin.test-d.js.map +1 -1
  468. package/dist/plugin/mock-json-plugin.d.ts +17 -0
  469. package/dist/plugin/mock-json-plugin.d.ts.map +1 -0
  470. package/dist/plugin/mock-json-plugin.flatten.d.ts +3 -0
  471. package/dist/plugin/mock-json-plugin.flatten.d.ts.map +1 -0
  472. package/dist/plugin/mock-json-plugin.flatten.js +124 -0
  473. package/dist/plugin/mock-json-plugin.flatten.js.map +1 -0
  474. package/dist/plugin/mock-json-plugin.js +101 -0
  475. package/dist/plugin/mock-json-plugin.js.map +1 -0
  476. package/dist/plugin/mock-json-plugin.test.d.ts +2 -0
  477. package/dist/plugin/mock-json-plugin.test.d.ts.map +1 -0
  478. package/dist/plugin/mock-json-plugin.test.js +164 -0
  479. package/dist/plugin/mock-json-plugin.test.js.map +1 -0
  480. package/dist/query-filter/change-conflict-in-version.d.ts.map +1 -1
  481. package/dist/query-filter/change-has-label.d.ts +9 -3
  482. package/dist/query-filter/change-has-label.d.ts.map +1 -1
  483. package/dist/query-filter/change-has-label.js +7 -4
  484. package/dist/query-filter/change-has-label.js.map +1 -1
  485. package/dist/query-filter/change-has-label.test.js +36 -11
  486. package/dist/query-filter/change-has-label.test.js.map +1 -1
  487. package/dist/query-filter/change-is-leaf.d.ts.map +1 -1
  488. package/dist/query-filter/change-set-element-in-ancestry-of.d.ts +30 -0
  489. package/dist/query-filter/change-set-element-in-ancestry-of.d.ts.map +1 -0
  490. package/dist/query-filter/change-set-element-in-ancestry-of.js +46 -0
  491. package/dist/query-filter/change-set-element-in-ancestry-of.js.map +1 -0
  492. package/dist/query-filter/change-set-element-in-ancestry-of.test.d.ts +2 -0
  493. package/dist/query-filter/change-set-element-in-ancestry-of.test.d.ts.map +1 -0
  494. package/dist/query-filter/change-set-element-in-ancestry-of.test.js +323 -0
  495. package/dist/query-filter/change-set-element-in-ancestry-of.test.js.map +1 -0
  496. package/dist/query-filter/change-set-element-in-symmetric-difference.d.ts +20 -0
  497. package/dist/query-filter/change-set-element-in-symmetric-difference.d.ts.map +1 -0
  498. package/dist/query-filter/change-set-element-in-symmetric-difference.js +36 -0
  499. package/dist/query-filter/change-set-element-in-symmetric-difference.js.map +1 -0
  500. package/dist/query-filter/change-set-element-in-symmetric-difference.test.d.ts +2 -0
  501. package/dist/query-filter/change-set-element-in-symmetric-difference.test.d.ts.map +1 -0
  502. package/dist/query-filter/change-set-element-in-symmetric-difference.test.js +369 -0
  503. package/dist/query-filter/change-set-element-in-symmetric-difference.test.js.map +1 -0
  504. package/dist/query-filter/change-set-element-is-leaf-of.d.ts +29 -0
  505. package/dist/query-filter/change-set-element-is-leaf-of.d.ts.map +1 -0
  506. package/dist/query-filter/change-set-element-is-leaf-of.js +91 -0
  507. package/dist/query-filter/change-set-element-is-leaf-of.js.map +1 -0
  508. package/dist/query-filter/change-set-element-is-leaf-of.test.d.ts +2 -0
  509. package/dist/query-filter/change-set-element-is-leaf-of.test.d.ts.map +1 -0
  510. package/dist/query-filter/change-set-element-is-leaf-of.test.js +515 -0
  511. package/dist/query-filter/change-set-element-is-leaf-of.test.js.map +1 -0
  512. package/dist/query-filter/change-set-has-label.d.ts +19 -3
  513. package/dist/query-filter/change-set-has-label.d.ts.map +1 -1
  514. package/dist/query-filter/change-set-has-label.js +17 -4
  515. package/dist/query-filter/change-set-has-label.js.map +1 -1
  516. package/dist/query-filter/change-set-has-label.test.js +13 -20
  517. package/dist/query-filter/change-set-has-label.test.js.map +1 -1
  518. package/dist/query-filter/change-set-is-ancestor-of.d.ts +51 -0
  519. package/dist/query-filter/change-set-is-ancestor-of.d.ts.map +1 -0
  520. package/dist/query-filter/change-set-is-ancestor-of.js +63 -0
  521. package/dist/query-filter/change-set-is-ancestor-of.js.map +1 -0
  522. package/dist/query-filter/change-set-is-ancestor-of.test.d.ts +2 -0
  523. package/dist/query-filter/change-set-is-ancestor-of.test.d.ts.map +1 -0
  524. package/dist/query-filter/change-set-is-ancestor-of.test.js +153 -0
  525. package/dist/query-filter/change-set-is-ancestor-of.test.js.map +1 -0
  526. package/dist/query-filter/change-set-is-descendant-of.d.ts +44 -0
  527. package/dist/query-filter/change-set-is-descendant-of.d.ts.map +1 -0
  528. package/dist/query-filter/change-set-is-descendant-of.js +56 -0
  529. package/dist/query-filter/change-set-is-descendant-of.js.map +1 -0
  530. package/dist/query-filter/change-set-is-descendant-of.test.d.ts +2 -0
  531. package/dist/query-filter/change-set-is-descendant-of.test.d.ts.map +1 -0
  532. package/dist/query-filter/change-set-is-descendant-of.test.js +137 -0
  533. package/dist/query-filter/change-set-is-descendant-of.test.js.map +1 -0
  534. package/dist/query-filter/index.d.ts +5 -6
  535. package/dist/query-filter/index.d.ts.map +1 -1
  536. package/dist/query-filter/index.js +5 -6
  537. package/dist/query-filter/index.js.map +1 -1
  538. package/dist/query-filter/version-change-in-difference.d.ts.map +1 -1
  539. package/dist/query-filter/version-change-in-symmetric-difference.d.ts.map +1 -1
  540. package/dist/repository/comparison-example.js +173 -0
  541. package/dist/repository/comparison-example.js.map +1 -0
  542. package/dist/repository/entity-repository.d.ts +53 -0
  543. package/dist/repository/entity-repository.d.ts.map +1 -0
  544. package/dist/repository/entity-repository.js +187 -0
  545. package/dist/repository/entity-repository.js.map +1 -0
  546. package/dist/repository/entity-repository.test.d.ts +2 -0
  547. package/dist/repository/entity-repository.test.d.ts.map +1 -0
  548. package/dist/repository/entity-repository.test.js +94 -0
  549. package/dist/repository/entity-repository.test.js.map +1 -0
  550. package/dist/repository/example.d.ts +6 -0
  551. package/dist/repository/example.d.ts.map +1 -0
  552. package/dist/repository/example.js +87 -0
  553. package/dist/repository/example.js.map +1 -0
  554. package/dist/repository/file-repository.d.ts +39 -0
  555. package/dist/repository/file-repository.d.ts.map +1 -0
  556. package/dist/repository/file-repository.js +93 -0
  557. package/dist/repository/file-repository.js.map +1 -0
  558. package/dist/repository/file-repository.test.d.ts +2 -0
  559. package/dist/repository/file-repository.test.d.ts.map +1 -0
  560. package/dist/repository/file-repository.test.js +165 -0
  561. package/dist/repository/file-repository.test.js.map +1 -0
  562. package/dist/repository/index.d.ts +6 -0
  563. package/dist/repository/index.d.ts.map +1 -0
  564. package/dist/repository/index.js +6 -0
  565. package/dist/repository/index.js.map +1 -0
  566. package/dist/repository/integration.test.d.ts +2 -0
  567. package/dist/repository/integration.test.d.ts.map +1 -0
  568. package/dist/repository/integration.test.js +136 -0
  569. package/dist/repository/integration.test.js.map +1 -0
  570. package/dist/repository/key-value-repository.d.ts +30 -0
  571. package/dist/repository/key-value-repository.d.ts.map +1 -0
  572. package/dist/repository/key-value-repository.js +60 -0
  573. package/dist/repository/key-value-repository.js.map +1 -0
  574. package/dist/repository/key-value-repository.test.d.ts +2 -0
  575. package/dist/repository/key-value-repository.test.d.ts.map +1 -0
  576. package/dist/repository/key-value-repository.test.js +122 -0
  577. package/dist/repository/key-value-repository.test.js.map +1 -0
  578. package/dist/repository/markdown-plugin-example.js +118 -0
  579. package/dist/repository/markdown-plugin-example.js.map +1 -0
  580. package/dist/repository/query-builder.d.ts +69 -0
  581. package/dist/repository/query-builder.d.ts.map +1 -0
  582. package/dist/repository/query-builder.js +155 -0
  583. package/dist/repository/query-builder.js.map +1 -0
  584. package/dist/repository/query-builder.test.d.ts +2 -0
  585. package/dist/repository/query-builder.test.d.ts.map +1 -0
  586. package/dist/repository/query-builder.test.js +244 -0
  587. package/dist/repository/query-builder.test.js.map +1 -0
  588. package/dist/repository/repository-manager.d.ts +27 -0
  589. package/dist/repository/repository-manager.d.ts.map +1 -0
  590. package/dist/repository/repository-manager.js +19 -0
  591. package/dist/repository/repository-manager.js.map +1 -0
  592. package/dist/repository/repository-manager.test.d.ts +2 -0
  593. package/dist/repository/repository-manager.test.d.ts.map +1 -0
  594. package/dist/repository/repository-manager.test.js +65 -0
  595. package/dist/repository/repository-manager.test.js.map +1 -0
  596. package/dist/repository/test-helpers.js +402 -0
  597. package/dist/repository/test-helpers.js.map +1 -0
  598. package/dist/schema-definition/definition.d.ts +406 -0
  599. package/dist/schema-definition/definition.d.ts.map +1 -0
  600. package/dist/schema-definition/definition.js +82 -0
  601. package/dist/schema-definition/definition.js.map +1 -0
  602. package/dist/schema-definition/definition.test-d.d.ts +2 -0
  603. package/dist/schema-definition/definition.test-d.d.ts.map +1 -0
  604. package/dist/schema-definition/definition.test-d.js +177 -0
  605. package/dist/schema-definition/definition.test-d.js.map +1 -0
  606. package/dist/schema-definition/definition.test.d.ts +2 -0
  607. package/dist/schema-definition/definition.test.d.ts.map +1 -0
  608. package/dist/schema-definition/definition.test.js +324 -0
  609. package/dist/schema-definition/definition.test.js.map +1 -0
  610. package/dist/schema-definition/index.d.ts +4 -0
  611. package/dist/schema-definition/index.d.ts.map +1 -0
  612. package/dist/schema-definition/index.js +4 -0
  613. package/dist/schema-definition/index.js.map +1 -0
  614. package/dist/schema-definition/json-type.d.ts +24 -0
  615. package/dist/schema-definition/json-type.d.ts.map +1 -0
  616. package/dist/schema-definition/json-type.js +42 -0
  617. package/dist/schema-definition/json-type.js.map +1 -0
  618. package/dist/schema-definition/json-type.test.d.ts +2 -0
  619. package/dist/schema-definition/json-type.test.d.ts.map +1 -0
  620. package/dist/schema-definition/json-type.test.js +21 -0
  621. package/dist/schema-definition/json-type.test.js.map +1 -0
  622. package/dist/schema-definition/lix-generated.test.d.ts +2 -0
  623. package/dist/schema-definition/lix-generated.test.d.ts.map +1 -0
  624. package/dist/schema-definition/lix-generated.test.js +127 -0
  625. package/dist/schema-definition/lix-generated.test.js.map +1 -0
  626. package/dist/schema-definition/validate-lix-schema.d.ts +65 -0
  627. package/dist/schema-definition/validate-lix-schema.d.ts.map +1 -0
  628. package/dist/schema-definition/validate-lix-schema.js +93 -0
  629. package/dist/schema-definition/validate-lix-schema.js.map +1 -0
  630. package/dist/schema-definition/validate-lix-schema.test.d.ts +2 -0
  631. package/dist/schema-definition/validate-lix-schema.test.d.ts.map +1 -0
  632. package/dist/schema-definition/validate-lix-schema.test.js +73 -0
  633. package/dist/schema-definition/validate-lix-schema.test.js.map +1 -0
  634. package/dist/server-protocol-handler/create-server-protocol-handler.d.ts +0 -1
  635. package/dist/server-protocol-handler/create-server-protocol-handler.d.ts.map +1 -1
  636. package/dist/server-protocol-handler/create-server-protocol-handler.js +0 -2
  637. package/dist/server-protocol-handler/create-server-protocol-handler.js.map +1 -1
  638. package/dist/server-protocol-handler/environment/create-in-memory-environment.d.ts.map +1 -1
  639. package/dist/server-protocol-handler/environment/create-in-memory-environment.js +5 -20
  640. package/dist/server-protocol-handler/environment/create-in-memory-environment.js.map +1 -1
  641. package/dist/server-protocol-handler/environment/create-in-memory-environment.test.js +13 -14
  642. package/dist/server-protocol-handler/environment/create-in-memory-environment.test.js.map +1 -1
  643. package/dist/server-protocol-handler/environment/environment.d.ts +0 -4
  644. package/dist/server-protocol-handler/environment/environment.d.ts.map +1 -1
  645. package/dist/server-protocol-handler/routes/get-v1.d.ts.map +1 -1
  646. package/dist/server-protocol-handler/routes/get-v1.js +1 -1
  647. package/dist/server-protocol-handler/routes/get-v1.js.map +1 -1
  648. package/dist/server-protocol-handler/routes/get-v1.test.js +11 -12
  649. package/dist/server-protocol-handler/routes/get-v1.test.js.map +1 -1
  650. package/dist/server-protocol-handler/routes/new-v1.d.ts.map +1 -1
  651. package/dist/server-protocol-handler/routes/new-v1.js +3 -5
  652. package/dist/server-protocol-handler/routes/new-v1.js.map +1 -1
  653. package/dist/server-protocol-handler/routes/new-v1.test.js +7 -8
  654. package/dist/server-protocol-handler/routes/new-v1.test.js.map +1 -1
  655. package/dist/server-protocol-handler/routes/pull-v1.test.js +48 -32
  656. package/dist/server-protocol-handler/routes/pull-v1.test.js.map +1 -1
  657. package/dist/server-protocol-handler/routes/push-v1.d.ts.map +1 -1
  658. package/dist/server-protocol-handler/routes/push-v1.js +2 -0
  659. package/dist/server-protocol-handler/routes/push-v1.js.map +1 -1
  660. package/dist/server-protocol-handler/routes/push-v1.test.js +22 -26
  661. package/dist/server-protocol-handler/routes/push-v1.test.js.map +1 -1
  662. package/dist/services/env-variables/index.d.ts +1 -1
  663. package/dist/services/env-variables/index.js +2 -2
  664. package/dist/services/env-variables/index.js.map +1 -1
  665. package/dist/services/telemetry/capture.d.ts.map +1 -1
  666. package/dist/snapshot/create-snapshot.d.ts +3 -14
  667. package/dist/snapshot/create-snapshot.d.ts.map +1 -1
  668. package/dist/snapshot/create-snapshot.js +14 -19
  669. package/dist/snapshot/create-snapshot.js.map +1 -1
  670. package/dist/snapshot/create-snapshot.test.js +49 -20
  671. package/dist/snapshot/create-snapshot.test.js.map +1 -1
  672. package/dist/snapshot/index.d.ts +1 -0
  673. package/dist/snapshot/index.d.ts.map +1 -1
  674. package/dist/snapshot/index.js +1 -0
  675. package/dist/snapshot/index.js.map +1 -1
  676. package/dist/snapshot/json-sha-256.d.ts +2 -1
  677. package/dist/snapshot/json-sha-256.d.ts.map +1 -1
  678. package/dist/snapshot/json-sha-256.js +1 -3
  679. package/dist/snapshot/json-sha-256.js.map +1 -1
  680. package/dist/snapshot/json-sha-256.test.js +40 -2
  681. package/dist/snapshot/json-sha-256.test.js.map +1 -1
  682. package/dist/snapshot/mock-json-snapshot.d.ts +1 -1
  683. package/dist/snapshot/mock-json-snapshot.d.ts.map +1 -1
  684. package/dist/snapshot/schema.d.ts +8 -0
  685. package/dist/snapshot/schema.d.ts.map +1 -0
  686. package/dist/snapshot/schema.js +12 -0
  687. package/dist/snapshot/schema.js.map +1 -0
  688. package/dist/snapshot/schema.test.d.ts +2 -0
  689. package/dist/snapshot/schema.test.d.ts.map +1 -0
  690. package/dist/snapshot/schema.test.js +116 -0
  691. package/dist/snapshot/schema.test.js.map +1 -0
  692. package/dist/state/create-changeset-for-transaction.d.ts +15 -0
  693. package/dist/state/create-changeset-for-transaction.d.ts.map +1 -0
  694. package/dist/state/create-changeset-for-transaction.js +237 -0
  695. package/dist/state/create-changeset-for-transaction.js.map +1 -0
  696. package/dist/state/entity-view-builder.d.ts +145 -0
  697. package/dist/state/entity-view-builder.d.ts.map +1 -0
  698. package/dist/state/entity-view-builder.js +280 -0
  699. package/dist/state/entity-view-builder.js.map +1 -0
  700. package/dist/state/entity-view-builder.test.d.ts +2 -0
  701. package/dist/state/entity-view-builder.test.d.ts.map +1 -0
  702. package/dist/state/entity-view-builder.test.js +523 -0
  703. package/dist/state/entity-view-builder.test.js.map +1 -0
  704. package/dist/state/get-version-record-by-id-or-throw.d.ts +6 -0
  705. package/dist/state/get-version-record-by-id-or-throw.d.ts.map +1 -0
  706. package/dist/state/get-version-record-by-id-or-throw.js +36 -0
  707. package/dist/state/get-version-record-by-id-or-throw.js.map +1 -0
  708. package/dist/state/handle-state-mutation.d.ts +18 -0
  709. package/dist/state/handle-state-mutation.d.ts.map +1 -0
  710. package/dist/state/handle-state-mutation.js +352 -0
  711. package/dist/state/handle-state-mutation.js.map +1 -0
  712. package/dist/state/handle-state-mutation.test.d.ts +2 -0
  713. package/dist/state/handle-state-mutation.test.d.ts.map +1 -0
  714. package/dist/state/handle-state-mutation.test.js +632 -0
  715. package/dist/state/handle-state-mutation.test.js.map +1 -0
  716. package/dist/state/schema.bench.d.ts +2 -0
  717. package/dist/state/schema.bench.d.ts.map +1 -0
  718. package/dist/state/schema.bench.js +36 -0
  719. package/dist/state/schema.bench.js.map +1 -0
  720. package/dist/state/schema.d.ts +56 -0
  721. package/dist/state/schema.d.ts.map +1 -0
  722. package/dist/state/schema.js +1052 -0
  723. package/dist/state/schema.js.map +1 -0
  724. package/dist/state/schema.test.d.ts +2 -0
  725. package/dist/state/schema.test.d.ts.map +1 -0
  726. package/dist/state/schema.test.js +2030 -0
  727. package/dist/state/schema.test.js.map +1 -0
  728. package/dist/state/validate-state-mutation.d.ts +13 -0
  729. package/dist/state/validate-state-mutation.d.ts.map +1 -0
  730. package/dist/state/validate-state-mutation.js +485 -0
  731. package/dist/state/validate-state-mutation.js.map +1 -0
  732. package/dist/state/validate-state-mutation.test.d.ts +2 -0
  733. package/dist/state/validate-state-mutation.test.d.ts.map +1 -0
  734. package/dist/state/validate-state-mutation.test.js +2024 -0
  735. package/dist/state/validate-state-mutation.test.js.map +1 -0
  736. package/dist/state-history/schema.d.ts +58 -0
  737. package/dist/state-history/schema.d.ts.map +1 -0
  738. package/dist/state-history/schema.js +104 -0
  739. package/dist/state-history/schema.js.map +1 -0
  740. package/dist/state-history/schema.test.d.ts +2 -0
  741. package/dist/state-history/schema.test.d.ts.map +1 -0
  742. package/dist/state-history/schema.test.js +701 -0
  743. package/dist/state-history/schema.test.js.map +1 -0
  744. package/dist/stored-schema/index.d.ts +2 -0
  745. package/dist/stored-schema/index.d.ts.map +1 -0
  746. package/dist/stored-schema/index.js +2 -0
  747. package/dist/stored-schema/index.js.map +1 -0
  748. package/dist/stored-schema/schema.d.ts +25 -0
  749. package/dist/stored-schema/schema.d.ts.map +1 -0
  750. package/dist/stored-schema/schema.js +48 -0
  751. package/dist/stored-schema/schema.js.map +1 -0
  752. package/dist/stored-schema/schema.test.d.ts +2 -0
  753. package/dist/stored-schema/schema.test.d.ts.map +1 -0
  754. package/dist/stored-schema/schema.test.js +192 -0
  755. package/dist/stored-schema/schema.test.js.map +1 -0
  756. package/dist/sync/get-diffing-rows.d.ts +12 -0
  757. package/dist/sync/get-diffing-rows.d.ts.map +1 -1
  758. package/dist/sync/get-diffing-rows.js +14 -0
  759. package/dist/sync/get-diffing-rows.js.map +1 -1
  760. package/dist/sync/merge-state.d.ts.map +1 -1
  761. package/dist/sync/merge-state.js +2 -1
  762. package/dist/sync/merge-state.js.map +1 -1
  763. package/dist/sync/pull-from-server.d.ts.map +1 -1
  764. package/dist/sync/pull-from-server.js +2 -1
  765. package/dist/sync/pull-from-server.js.map +1 -1
  766. package/dist/sync/pull-from-server.test.js +32 -28
  767. package/dist/sync/pull-from-server.test.js.map +1 -1
  768. package/dist/sync/push-to-server.d.ts +10 -1
  769. package/dist/sync/push-to-server.d.ts.map +1 -1
  770. package/dist/sync/push-to-server.js +10 -1
  771. package/dist/sync/push-to-server.js.map +1 -1
  772. package/dist/sync/push-to-server.test.js +62 -63
  773. package/dist/sync/push-to-server.test.js.map +1 -1
  774. package/dist/sync/sync-process.d.ts +1 -1
  775. package/dist/sync/sync-process.d.ts.map +1 -1
  776. package/dist/sync/sync-process.js +1 -2
  777. package/dist/sync/sync-process.js.map +1 -1
  778. package/dist/sync/sync-process.test.js +20 -17
  779. package/dist/sync/sync-process.test.js.map +1 -1
  780. package/dist/thread/create-thread-comment.d.ts +18 -0
  781. package/dist/thread/create-thread-comment.d.ts.map +1 -0
  782. package/dist/thread/create-thread-comment.js +47 -0
  783. package/dist/thread/create-thread-comment.js.map +1 -0
  784. package/dist/thread/create-thread-comment.test.d.ts +2 -0
  785. package/dist/thread/create-thread-comment.test.d.ts.map +1 -0
  786. package/dist/thread/create-thread-comment.test.js +51 -0
  787. package/dist/thread/create-thread-comment.test.js.map +1 -0
  788. package/dist/thread/create-thread.d.ts +28 -0
  789. package/dist/thread/create-thread.d.ts.map +1 -0
  790. package/dist/thread/create-thread.js +58 -0
  791. package/dist/thread/create-thread.js.map +1 -0
  792. package/dist/thread/create-thread.test.d.ts +2 -0
  793. package/dist/thread/create-thread.test.d.ts.map +1 -0
  794. package/dist/thread/create-thread.test.js +26 -0
  795. package/dist/thread/create-thread.test.js.map +1 -0
  796. package/dist/thread/index.d.ts +4 -0
  797. package/dist/thread/index.d.ts.map +1 -0
  798. package/dist/thread/index.js +4 -0
  799. package/dist/thread/index.js.map +1 -0
  800. package/dist/thread/schema.d.ts +59 -0
  801. package/dist/thread/schema.d.ts.map +1 -0
  802. package/dist/thread/schema.js +66 -0
  803. package/dist/thread/schema.js.map +1 -0
  804. package/dist/thread/schema.test.d.ts +2 -0
  805. package/dist/thread/schema.test.d.ts.map +1 -0
  806. package/dist/thread/schema.test.js +60 -0
  807. package/dist/thread/schema.test.js.map +1 -0
  808. package/dist/version/create-version.d.ts +9 -17
  809. package/dist/version/create-version.d.ts.map +1 -1
  810. package/dist/version/create-version.js +30 -57
  811. package/dist/version/create-version.js.map +1 -1
  812. package/dist/version/create-version.test.js +70 -113
  813. package/dist/version/create-version.test.js.map +1 -1
  814. package/dist/version/index.d.ts +1 -5
  815. package/dist/version/index.d.ts.map +1 -1
  816. package/dist/version/index.js +1 -5
  817. package/dist/version/index.js.map +1 -1
  818. package/dist/version/schema.d.ts +73 -0
  819. package/dist/version/schema.d.ts.map +1 -0
  820. package/dist/version/schema.js +135 -0
  821. package/dist/version/schema.js.map +1 -0
  822. package/dist/version/schema.test.d.ts +2 -0
  823. package/dist/version/schema.test.d.ts.map +1 -0
  824. package/dist/version/schema.test.js +661 -0
  825. package/dist/version/schema.test.js.map +1 -0
  826. package/dist/version/switch-version.d.ts +4 -4
  827. package/dist/version/switch-version.d.ts.map +1 -1
  828. package/dist/version/switch-version.js +6 -62
  829. package/dist/version/switch-version.js.map +1 -1
  830. package/dist/version/switch-version.test.js +14 -214
  831. package/dist/version/switch-version.test.js.map +1 -1
  832. package/dist/zettel-ast/index.d.ts +11 -0
  833. package/dist/zettel-ast/index.d.ts.map +1 -0
  834. package/dist/zettel-ast/index.js +11 -0
  835. package/dist/zettel-ast/index.js.map +1 -0
  836. package/package.json +10 -9
  837. package/src/account/create-account.test.ts +49 -4
  838. package/src/account/create-account.ts +36 -6
  839. package/src/account/index.ts +5 -1
  840. package/src/account/schema.test.ts +370 -0
  841. package/src/account/schema.ts +76 -0
  842. package/src/account/switch-account.test.ts +29 -6
  843. package/src/account/switch-account.ts +12 -3
  844. package/src/change/index.ts +1 -2
  845. package/src/change/schema.test.ts +284 -0
  846. package/src/change/schema.ts +93 -0
  847. package/src/change-author/index.ts +1 -0
  848. package/src/change-author/schema.test.ts +300 -0
  849. package/src/change-author/schema.ts +48 -0
  850. package/src/change-conflict/create-change-conflict.test.ts +14 -11
  851. package/src/change-conflict/create-change-conflict.ts +29 -6
  852. package/src/change-conflict/detect-change-conflicts.test.ts +18 -15
  853. package/src/change-conflict/detect-change-conflicts.ts +3 -0
  854. package/src/change-conflict/detect-diverging-entity-conflict.test.ts +24 -21
  855. package/src/change-conflict/detect-diverging-entity-conflict.ts +4 -1
  856. package/src/change-conflict/garbage-collect-change-conflicts.test.ts +16 -15
  857. package/src/change-conflict/garbage-collect-change-conflicts.ts +3 -0
  858. package/src/change-conflict/resolve-conflict-by-selecting.test.ts +18 -8
  859. package/src/change-conflict/resolve-conflict-by-selecting.ts +3 -2
  860. package/src/change-proposal/create-change-proposal.test.ts +106 -0
  861. package/src/change-proposal/create-change-proposal.ts +71 -0
  862. package/src/change-proposal/database-schema.test.ts +180 -0
  863. package/src/change-proposal/database-schema.ts +32 -0
  864. package/src/change-proposal/index.ts +2 -0
  865. package/src/change-set/apply-change-set.test.ts +469 -0
  866. package/src/change-set/apply-change-set.ts +186 -0
  867. package/src/change-set/create-change-set.test.ts +126 -27
  868. package/src/change-set/create-change-set.ts +117 -41
  869. package/src/change-set/create-checkpoint.test.ts +387 -0
  870. package/src/change-set/create-checkpoint.ts +101 -0
  871. package/src/change-set/create-merge-change-set.test.ts +237 -0
  872. package/src/change-set/create-merge-change-set.ts +99 -0
  873. package/src/change-set/create-transition-change-set.test.ts +245 -0
  874. package/src/change-set/create-transition-change-set.ts +149 -0
  875. package/src/change-set/create-undo-change-set.test.ts +329 -0
  876. package/src/change-set/create-undo-change-set.ts +147 -0
  877. package/src/change-set/index.ts +17 -1
  878. package/src/change-set/schema.test.ts +981 -0
  879. package/src/change-set/schema.ts +207 -0
  880. package/src/database/execute-sync.test.ts +60 -72
  881. package/src/database/execute-sync.ts +26 -27
  882. package/src/database/graph-traversal-mode.ts +75 -0
  883. package/src/database/index.ts +3 -2
  884. package/src/database/init-db.ts +82 -66
  885. package/src/database/kysely-plugin/json-column-plugin.ts +215 -0
  886. package/src/database/kysely-plugin/parse-jsonb-plugin-v1.ts +5 -10
  887. package/src/database/kysely-plugin/parse-jsonb-plugin-v2.ts +1 -1
  888. package/src/database/kysely-plugin/serialize-jsonb-plugin.test.ts +177 -2
  889. package/src/database/kysely-plugin/serialize-jsonb-plugin.ts +186 -87
  890. package/src/database/kysely-plugin/view-insert-returning-error-plugin.test.ts +62 -0
  891. package/src/database/kysely-plugin/view-insert-returning-error-plugin.ts +49 -0
  892. package/src/database/schema.ts +100 -267
  893. package/src/entity-views/entity-state-all.test.ts +445 -0
  894. package/src/entity-views/entity-state-all.ts +506 -0
  895. package/src/entity-views/entity-state-history.test.ts +325 -0
  896. package/src/entity-views/entity-state-history.ts +226 -0
  897. package/src/entity-views/entity-state.test.ts +592 -0
  898. package/src/entity-views/entity-state.ts +502 -0
  899. package/src/entity-views/entity-view-builder.test.ts +293 -0
  900. package/src/entity-views/entity-view-builder.ts +148 -0
  901. package/src/entity-views/index.ts +1 -0
  902. package/src/entity-views/types.test.ts +99 -0
  903. package/src/entity-views/types.ts +328 -0
  904. package/src/file/file-handlers.test.ts +174 -0
  905. package/src/file/file-handlers.ts +364 -0
  906. package/src/file/index.ts +5 -1
  907. package/src/file/materialize-file-data-at-changeset.ts +123 -0
  908. package/src/file/materialize-file-data.test.ts +107 -0
  909. package/src/file/materialize-file-data.ts +120 -0
  910. package/src/file/schema.test.ts +990 -0
  911. package/src/file/schema.ts +300 -0
  912. package/src/file/store-detected-change-schema.test.ts +248 -0
  913. package/src/file/store-detected-change-schema.ts +52 -0
  914. package/src/file/unknown-file-fallback-plugin.test.ts +368 -0
  915. package/src/file/unknown-file-fallback-plugin.ts +95 -0
  916. package/src/hooks/create-hooks.test.ts +125 -0
  917. package/src/hooks/create-hooks.ts +101 -0
  918. package/src/hooks/index.ts +1 -0
  919. package/src/index.ts +10 -6
  920. package/src/key-value/index.ts +1 -0
  921. package/src/key-value/schema.test.ts +179 -0
  922. package/src/key-value/schema.ts +37 -0
  923. package/src/label/create-label.test.ts +234 -0
  924. package/src/label/create-label.ts +61 -0
  925. package/src/label/index.ts +2 -0
  926. package/src/label/schema.test.ts +92 -0
  927. package/src/label/schema.ts +40 -0
  928. package/src/lix/index.ts +3 -5
  929. package/src/lix/new-lix.test.ts +213 -17
  930. package/src/lix/new-lix.ts +395 -8
  931. package/src/lix/open-lix.test.ts +65 -26
  932. package/src/lix/open-lix.ts +131 -22
  933. package/src/lix/storage/in-memory.test.ts +180 -0
  934. package/src/lix/storage/in-memory.ts +69 -0
  935. package/src/lix/storage/lix-storage-adapter.ts +16 -0
  936. package/src/lix/storage/opfs.test.ts +215 -0
  937. package/src/lix/storage/opfs.ts +175 -0
  938. package/src/log/create-lix-own-log.test.ts +119 -0
  939. package/src/log/create-lix-own-log.ts +124 -0
  940. package/src/log/create-log.ts +52 -0
  941. package/src/log/index.ts +2 -0
  942. package/src/log/schema.test.ts +140 -0
  943. package/src/log/schema.ts +55 -0
  944. package/src/observe/create-observe.test.ts +501 -0
  945. package/src/observe/create-observe.ts +146 -0
  946. package/src/observe/index.ts +1 -0
  947. package/src/observe/lix-observable.test.ts +247 -0
  948. package/src/observe/lix-observable.ts +92 -0
  949. package/src/plugin/index.ts +2 -2
  950. package/src/plugin/lix-plugin.test-d.ts +26 -15
  951. package/src/plugin/lix-plugin.ts +41 -50
  952. package/src/plugin/mock-json-plugin.flatten.ts +161 -0
  953. package/src/plugin/mock-json-plugin.test.ts +214 -0
  954. package/src/plugin/mock-json-plugin.ts +113 -0
  955. package/src/query-filter/change-has-label.test.ts +38 -11
  956. package/src/query-filter/change-has-label.ts +8 -4
  957. package/src/query-filter/change-set-element-in-ancestry-of.test.ts +354 -0
  958. package/src/query-filter/change-set-element-in-ancestry-of.ts +64 -0
  959. package/src/query-filter/change-set-element-in-symmetric-difference.test.ts +410 -0
  960. package/src/{change-set → query-filter}/change-set-element-in-symmetric-difference.ts +2 -1
  961. package/src/query-filter/change-set-element-is-leaf-of.test.ts +564 -0
  962. package/src/query-filter/change-set-element-is-leaf-of.ts +110 -0
  963. package/src/query-filter/change-set-has-label.test.ts +13 -21
  964. package/src/query-filter/change-set-has-label.ts +18 -4
  965. package/src/query-filter/change-set-is-ancestor-of.test.ts +178 -0
  966. package/src/query-filter/change-set-is-ancestor-of.ts +77 -0
  967. package/src/query-filter/change-set-is-descendant-of.test.ts +169 -0
  968. package/src/query-filter/change-set-is-descendant-of.ts +70 -0
  969. package/src/query-filter/index.ts +5 -6
  970. package/src/schema-definition/definition.test-d.ts +253 -0
  971. package/src/schema-definition/definition.test.ts +377 -0
  972. package/src/schema-definition/definition.ts +445 -0
  973. package/src/schema-definition/index.ts +13 -0
  974. package/src/schema-definition/json-type.test.ts +30 -0
  975. package/src/schema-definition/json-type.ts +53 -0
  976. package/src/schema-definition/validate-lix-schema.test.ts +85 -0
  977. package/src/schema-definition/validate-lix-schema.ts +108 -0
  978. package/src/server-protocol-handler/create-server-protocol-handler.ts +0 -4
  979. package/src/server-protocol-handler/environment/create-in-memory-environment.test.ts +13 -14
  980. package/src/server-protocol-handler/environment/create-in-memory-environment.ts +5 -24
  981. package/src/server-protocol-handler/environment/environment.ts +0 -5
  982. package/src/server-protocol-handler/routes/get-v1.test.ts +11 -12
  983. package/src/server-protocol-handler/routes/get-v1.ts +3 -1
  984. package/src/server-protocol-handler/routes/new-v1.test.ts +7 -8
  985. package/src/server-protocol-handler/routes/new-v1.ts +3 -5
  986. package/src/server-protocol-handler/routes/pull-v1.test.ts +49 -33
  987. package/src/server-protocol-handler/routes/pull-v1.ts +1 -1
  988. package/src/server-protocol-handler/routes/push-v1.test.ts +26 -27
  989. package/src/server-protocol-handler/routes/push-v1.ts +4 -1
  990. package/src/snapshot/schema.test.ts +155 -0
  991. package/src/snapshot/schema.ts +21 -0
  992. package/src/state/create-changeset-for-transaction.ts +321 -0
  993. package/src/state/get-version-record-by-id-or-throw.ts +51 -0
  994. package/src/state/handle-state-mutation.test.ts +761 -0
  995. package/src/state/handle-state-mutation.ts +418 -0
  996. package/src/state/schema.bench.ts +43 -0
  997. package/src/state/schema.test.ts +2416 -0
  998. package/src/state/schema.ts +1288 -0
  999. package/src/state/validate-state-mutation.test.ts +2353 -0
  1000. package/src/state/validate-state-mutation.ts +664 -0
  1001. package/src/state-history/schema.test.ts +827 -0
  1002. package/src/state-history/schema.ts +198 -0
  1003. package/src/stored-schema/index.ts +1 -0
  1004. package/src/stored-schema/schema.test.ts +240 -0
  1005. package/src/stored-schema/schema.ts +67 -0
  1006. package/src/sync/get-diffing-rows.ts +16 -0
  1007. package/src/sync/merge-state.ts +7 -4
  1008. package/src/sync/pull-from-server.test.ts +33 -28
  1009. package/src/sync/pull-from-server.ts +4 -2
  1010. package/src/sync/push-to-server.test.ts +77 -81
  1011. package/src/sync/push-to-server.ts +11 -2
  1012. package/src/sync/sync-process.test.ts +21 -18
  1013. package/src/sync/sync-process.ts +2 -3
  1014. package/src/thread/create-thread-comment.test.ts +63 -0
  1015. package/src/thread/create-thread-comment.ts +56 -0
  1016. package/src/thread/create-thread.test.ts +32 -0
  1017. package/src/thread/create-thread.ts +83 -0
  1018. package/src/thread/index.ts +8 -0
  1019. package/src/thread/schema.test.ts +76 -0
  1020. package/src/thread/schema.ts +85 -0
  1021. package/src/version/create-version.test.ts +78 -125
  1022. package/src/version/create-version.ts +37 -64
  1023. package/src/version/index.ts +5 -6
  1024. package/src/version/schema.test.ts +794 -0
  1025. package/src/version/schema.ts +149 -0
  1026. package/src/version/switch-version.test.ts +14 -275
  1027. package/src/version/switch-version.ts +8 -78
  1028. package/src/zettel-ast/index.ts +10 -0
  1029. package/src/account/database-schema.test.ts +0 -184
  1030. package/src/account/database-schema.ts +0 -54
  1031. package/src/change/apply-changes.test.ts +0 -268
  1032. package/src/change/apply-changes.ts +0 -114
  1033. package/src/change/create-change.test.ts +0 -296
  1034. package/src/change/create-change.ts +0 -129
  1035. package/src/change/mock-change.ts +0 -21
  1036. package/src/change-schema/README.md +0 -3
  1037. package/src/change-schema/index.ts +0 -4
  1038. package/src/change-schema/types.test-d.ts +0 -52
  1039. package/src/change-schema/types.ts +0 -53
  1040. package/src/change-set/change-set-element-in-symmetric-difference.test.ts +0 -128
  1041. package/src/database/apply-schema.ts +0 -272
  1042. package/src/database/init-db.test.ts +0 -626
  1043. package/src/database/mutation-log/database-schema.ts +0 -128
  1044. package/src/database/mutation-log/lix-session.ts +0 -19
  1045. package/src/discussion/create-comment.ts +0 -18
  1046. package/src/discussion/create-discussion.test.ts +0 -45
  1047. package/src/discussion/create-discussion.ts +0 -48
  1048. package/src/discussion/index.ts +0 -2
  1049. package/src/file/validate-file-path.test.ts +0 -44
  1050. package/src/file/validate-file-path.ts +0 -60
  1051. package/src/file-queue/file-handlers.ts +0 -267
  1052. package/src/file-queue/file-queue-process.test.ts +0 -456
  1053. package/src/file-queue/file-queue-process.ts +0 -108
  1054. package/src/file-queue/file-queue-settled.test.ts +0 -56
  1055. package/src/file-queue/file-queue-settled.ts +0 -31
  1056. package/src/file-queue/index.ts +0 -1
  1057. package/src/file-queue/with-skip-file-queue.test.ts +0 -158
  1058. package/src/file-queue/with-skip-file-queue.ts +0 -33
  1059. package/src/key-value/database-schema.test.ts +0 -140
  1060. package/src/key-value/database-schema.ts +0 -66
  1061. package/src/lix/close-lix.ts +0 -8
  1062. package/src/lix/merge.get-leaf-changes-only-in-source.test.ts +0 -143
  1063. package/src/lix/merge.get-leaf-changes-only-in-source.ts +0 -46
  1064. package/src/lix/merge.test.ts +0 -858
  1065. package/src/lix/merge.ts +0 -244
  1066. package/src/lix/open-lix-in-memory.test.ts +0 -34
  1067. package/src/lix/open-lix-in-memory.ts +0 -28
  1068. package/src/lix/to-blob.ts +0 -14
  1069. package/src/own-change-control/apply-own-change.test.ts +0 -361
  1070. package/src/own-change-control/apply-own-change.ts +0 -110
  1071. package/src/own-change-control/change-controlled-tables.test.ts +0 -69
  1072. package/src/own-change-control/change-controlled-tables.ts +0 -102
  1073. package/src/own-change-control/database-triggers.test.ts +0 -259
  1074. package/src/own-change-control/database-triggers.ts +0 -189
  1075. package/src/own-change-control/index.ts +0 -1
  1076. package/src/own-change-control/with-skip-own-change-control.test.ts +0 -57
  1077. package/src/own-change-control/with-skip-own-change-control.ts +0 -34
  1078. package/src/plugin/load-plugin.ts +0 -37
  1079. package/src/plugin/with-transaction.ts +0 -22
  1080. package/src/query-filter/change-conflict-in-version.test.ts +0 -62
  1081. package/src/query-filter/change-conflict-in-version.ts +0 -25
  1082. package/src/query-filter/change-in-version.test.ts +0 -82
  1083. package/src/query-filter/change-in-version.ts +0 -31
  1084. package/src/query-filter/change-is-leaf-in-version.test.ts +0 -77
  1085. package/src/query-filter/change-is-leaf-in-version.ts +0 -36
  1086. package/src/query-filter/change-is-leaf-of.bench.ts +0 -175
  1087. package/src/query-filter/change-is-leaf-of.test.ts +0 -84
  1088. package/src/query-filter/change-is-leaf-of.ts +0 -46
  1089. package/src/query-filter/change-is-leaf.test.ts +0 -140
  1090. package/src/query-filter/change-is-leaf.ts +0 -25
  1091. package/src/query-filter/change-is-lowest-common-ancestor-of.test.ts +0 -173
  1092. package/src/query-filter/change-is-lowest-common-ancestor-of.ts +0 -57
  1093. package/src/query-filter/version-change-in-difference.test.ts +0 -105
  1094. package/src/query-filter/version-change-in-difference.ts +0 -37
  1095. package/src/query-filter/version-change-in-symmetric-difference.test.ts +0 -104
  1096. package/src/query-filter/version-change-in-symmetric-difference.ts +0 -52
  1097. package/src/snapshot/create-snapshot.test.ts +0 -68
  1098. package/src/snapshot/create-snapshot.ts +0 -40
  1099. package/src/snapshot/index.ts +0 -2
  1100. package/src/snapshot/json-sha-256.test.ts +0 -12
  1101. package/src/snapshot/json-sha-256.ts +0 -35
  1102. package/src/snapshot/mock-json-snapshot.ts +0 -14
  1103. package/src/version/merge-version.test.ts +0 -530
  1104. package/src/version/merge-version.ts +0 -88
  1105. package/src/version/update-changes-in-version.test.ts +0 -371
  1106. package/src/version/update-changes-in-version.ts +0 -47
@@ -0,0 +1,2353 @@
1
+ import { test, expect } from "vitest";
2
+ import { openLix } from "../lix/open-lix.js";
3
+ import { validateStateMutation } from "./validate-state-mutation.js";
4
+ import type { LixSchemaDefinition } from "../schema-definition/definition.js";
5
+ import { sql } from "kysely";
6
+ import { createVersion } from "../version/create-version.js";
7
+ import type { ChangeSetElement } from "../change-set/schema.js";
8
+
9
+ test("throws if the schema is not a valid lix schema", async () => {
10
+ const lix = await openLix({});
11
+
12
+ const schema = {
13
+ type: "object",
14
+ "x-lix-version": "1.0",
15
+ properties: {
16
+ name: { type: "string" },
17
+ },
18
+ required: ["name"],
19
+ additionalProperties: false,
20
+ // @ts-expect-error - x-version is missing
21
+ } as const satisfies LixSchemaDefinition;
22
+
23
+ const activeVersion = await lix.db
24
+ .selectFrom("active_version")
25
+ .select("version_id")
26
+ .executeTakeFirstOrThrow();
27
+
28
+ expect(() =>
29
+ validateStateMutation({
30
+ lix,
31
+ // @ts-expect-error - x-key is missing
32
+ schema,
33
+ snapshot_content: {},
34
+ operation: "insert",
35
+ version_id: activeVersion.version_id,
36
+ })
37
+ ).toThrowError();
38
+ });
39
+
40
+ test("inserts the version and active version schemas to enable validation", async () => {
41
+ const lix = await openLix({});
42
+
43
+ const result = await lix.db
44
+ .selectFrom("stored_schema")
45
+ .where("key", "in", ["lix_version", "lix_active_version"])
46
+ .selectAll()
47
+ .execute();
48
+
49
+ expect(result.length).toBeGreaterThan(0);
50
+ });
51
+
52
+ test("valid lix schema with a valid snapshot passes", async () => {
53
+ const lix = await openLix({});
54
+
55
+ const schema = {
56
+ type: "object",
57
+ "x-lix-version": "1.0",
58
+ "x-lix-key": "mock",
59
+ properties: {
60
+ name: { type: "string" },
61
+ },
62
+ required: ["name"],
63
+ additionalProperties: false,
64
+ } as const satisfies LixSchemaDefinition;
65
+
66
+ const snapshot = {
67
+ content: {
68
+ name: "John",
69
+ },
70
+ };
71
+
72
+ const activeVersion = await lix.db
73
+ .selectFrom("active_version")
74
+ .select("version_id")
75
+ .executeTakeFirstOrThrow();
76
+
77
+ expect(() =>
78
+ validateStateMutation({
79
+ lix,
80
+ schema,
81
+ snapshot_content: snapshot.content,
82
+ operation: "insert",
83
+ version_id: activeVersion.version_id,
84
+ })
85
+ ).not.toThrowError();
86
+ });
87
+
88
+ test("an invalid snapshot fails", async () => {
89
+ const lix = await openLix({});
90
+
91
+ const schema = {
92
+ type: "object",
93
+ "x-lix-version": "1.0",
94
+ "x-lix-key": "mock",
95
+ properties: {
96
+ name: { type: "string" },
97
+ },
98
+ required: ["name"],
99
+ additionalProperties: false,
100
+ } as const satisfies LixSchemaDefinition;
101
+
102
+ const snapshot = {
103
+ content: {
104
+ foo: "John",
105
+ },
106
+ };
107
+
108
+ const activeVersion = await lix.db
109
+ .selectFrom("active_version")
110
+ .select("version_id")
111
+ .executeTakeFirstOrThrow();
112
+
113
+ expect(() =>
114
+ validateStateMutation({
115
+ lix,
116
+ schema,
117
+ snapshot_content: snapshot.content,
118
+ operation: "insert",
119
+ version_id: activeVersion.version_id,
120
+ })
121
+ ).toThrowError();
122
+ });
123
+
124
+ test("passes when primary key is unique", async () => {
125
+ const lix = await openLix({});
126
+
127
+ const schema = {
128
+ type: "object",
129
+ "x-lix-version": "1.0",
130
+ "x-lix-key": "user",
131
+ "x-lix-primary-key": ["id"],
132
+ properties: {
133
+ id: { type: "string" },
134
+ name: { type: "string" },
135
+ },
136
+ required: ["id", "name"],
137
+ additionalProperties: false,
138
+ } as const satisfies LixSchemaDefinition;
139
+
140
+ const snapshot = {
141
+ content: {
142
+ id: "user1",
143
+ name: "John",
144
+ },
145
+ };
146
+
147
+ const activeVersion = await lix.db
148
+ .selectFrom("active_version")
149
+ .select("version_id")
150
+ .executeTakeFirstOrThrow();
151
+
152
+ expect(() =>
153
+ validateStateMutation({
154
+ lix,
155
+ schema,
156
+ snapshot_content: snapshot.content,
157
+ operation: "insert",
158
+ version_id: activeVersion.version_id,
159
+ })
160
+ ).not.toThrowError();
161
+ });
162
+
163
+ test("throws when primary key violates uniqueness constraint", async () => {
164
+ const lix = await openLix({});
165
+
166
+ const schema = {
167
+ type: "object",
168
+ "x-lix-version": "1.0",
169
+ "x-lix-key": "user",
170
+ "x-lix-primary-key": ["id"],
171
+ properties: {
172
+ id: { type: "string" },
173
+ name: { type: "string" },
174
+ },
175
+ required: ["id", "name"],
176
+ additionalProperties: false,
177
+ } as const satisfies LixSchemaDefinition;
178
+
179
+ // Store the schema first
180
+ await lix.db.insertInto("stored_schema").values({ value: schema }).execute();
181
+
182
+ // Insert first user into state
183
+ await lix.db
184
+ .insertInto("state_all")
185
+ .values({
186
+ entity_id: "user1",
187
+ file_id: "file1",
188
+ schema_key: "user",
189
+ plugin_key: "test_plugin",
190
+ version_id: lix.db.selectFrom("active_version").select("version_id"),
191
+ snapshot_content: { id: "user1", name: "John" },
192
+ schema_version: "1.0",
193
+ })
194
+ .execute();
195
+
196
+ // Try to insert another user with same primary key
197
+ const duplicateSnapshot = {
198
+ content: {
199
+ id: "user1",
200
+ name: "Jane",
201
+ },
202
+ };
203
+
204
+ const activeVersion = await lix.db
205
+ .selectFrom("active_version")
206
+ .select("version_id")
207
+ .executeTakeFirstOrThrow();
208
+
209
+ expect(() =>
210
+ validateStateMutation({
211
+ lix,
212
+ schema,
213
+ snapshot_content: duplicateSnapshot.content,
214
+ operation: "insert",
215
+ version_id: activeVersion.version_id,
216
+ })
217
+ ).toThrowError("Primary key constraint violation");
218
+ });
219
+
220
+ test("handles composite primary keys", async () => {
221
+ const lix = await openLix({});
222
+
223
+ const schema = {
224
+ type: "object",
225
+ "x-lix-version": "1.0",
226
+ "x-lix-key": "user_role",
227
+ "x-lix-primary-key": ["user_id", "role_id"],
228
+ properties: {
229
+ user_id: { type: "string" },
230
+ role_id: { type: "string" },
231
+ assigned_date: { type: "string" },
232
+ },
233
+ required: ["user_id", "role_id", "assigned_date"],
234
+ additionalProperties: false,
235
+ } as const satisfies LixSchemaDefinition;
236
+
237
+ // Store the schema first
238
+ await lix.db.insertInto("stored_schema").values({ value: schema }).execute();
239
+
240
+ // Insert first user-role into state
241
+ await lix.db
242
+ .insertInto("state_all")
243
+ .values({
244
+ entity_id: "user_role1",
245
+ file_id: "file1",
246
+ schema_key: "user_role",
247
+ plugin_key: "test_plugin",
248
+ version_id: lix.db.selectFrom("active_version").select("version_id"),
249
+ snapshot_content: {
250
+ user_id: "user1",
251
+ role_id: "admin",
252
+ assigned_date: "2024-01-01",
253
+ },
254
+ schema_version: "1.0",
255
+ })
256
+ .execute();
257
+
258
+ const activeVersion = await lix.db
259
+ .selectFrom("active_version")
260
+ .select("version_id")
261
+ .executeTakeFirstOrThrow();
262
+
263
+ // This should pass (different composite key)
264
+ expect(() =>
265
+ validateStateMutation({
266
+ lix,
267
+ schema,
268
+ snapshot_content: {
269
+ user_id: "user1",
270
+ role_id: "editor",
271
+ assigned_date: "2024-01-02",
272
+ },
273
+ operation: "insert",
274
+ version_id: activeVersion.version_id,
275
+ })
276
+ ).not.toThrowError();
277
+
278
+ // This should fail (same composite key)
279
+ expect(() =>
280
+ validateStateMutation({
281
+ lix,
282
+ schema,
283
+ snapshot_content: {
284
+ user_id: "user1",
285
+ role_id: "admin",
286
+ assigned_date: "2024-01-03",
287
+ },
288
+ operation: "insert",
289
+ version_id: activeVersion.version_id,
290
+ })
291
+ ).toThrowError("Primary key constraint violation");
292
+ });
293
+
294
+ test("passes when unique constraint is satisfied", async () => {
295
+ const lix = await openLix({});
296
+
297
+ const activeVersion = await lix.db
298
+ .selectFrom("active_version")
299
+ .select("version_id")
300
+ .executeTakeFirstOrThrow();
301
+
302
+ const schema = {
303
+ type: "object",
304
+ "x-lix-version": "1.0",
305
+ "x-lix-key": "user",
306
+ "x-lix-primary-key": ["id"],
307
+ "x-lix-unique": [["email"], ["username"]],
308
+ properties: {
309
+ id: { type: "string" },
310
+ email: { type: "string" },
311
+ username: { type: "string" },
312
+ name: { type: "string" },
313
+ },
314
+ required: ["id", "email", "username", "name"],
315
+ additionalProperties: false,
316
+ } as const satisfies LixSchemaDefinition;
317
+
318
+ const snapshot = {
319
+ content: {
320
+ id: "user1",
321
+ email: "john@example.com",
322
+ username: "john_doe",
323
+ name: "John Doe",
324
+ },
325
+ };
326
+
327
+ expect(() =>
328
+ validateStateMutation({
329
+ lix,
330
+ schema,
331
+ snapshot_content: snapshot.content,
332
+ version_id: activeVersion.version_id,
333
+ operation: "insert",
334
+ })
335
+ ).not.toThrowError();
336
+ });
337
+
338
+ test("throws when single field unique constraint is violated", async () => {
339
+ const lix = await openLix({});
340
+
341
+ const schema = {
342
+ type: "object",
343
+ "x-lix-version": "1.0",
344
+ "x-lix-key": "user",
345
+ "x-lix-primary-key": ["id"],
346
+ "x-lix-unique": [["email"], ["username"]],
347
+ properties: {
348
+ id: { type: "string" },
349
+ email: { type: "string" },
350
+ username: { type: "string" },
351
+ name: { type: "string" },
352
+ },
353
+ required: ["id", "email", "username", "name"],
354
+ additionalProperties: false,
355
+ } as const satisfies LixSchemaDefinition;
356
+
357
+ // Store the schema first
358
+ await lix.db.insertInto("stored_schema").values({ value: schema }).execute();
359
+
360
+ // Insert first user into state
361
+ await lix.db
362
+ .insertInto("state_all")
363
+ .values({
364
+ entity_id: "user1",
365
+ file_id: "file1",
366
+ schema_key: "user",
367
+ plugin_key: "test_plugin",
368
+ version_id: lix.db.selectFrom("active_version").select("version_id"),
369
+ snapshot_content: {
370
+ id: "user1",
371
+ email: "john@example.com",
372
+ username: "john_doe",
373
+ name: "John Doe",
374
+ },
375
+ schema_version: "1.0",
376
+ })
377
+ .execute();
378
+
379
+ // Try to insert another user with same email (unique constraint violation)
380
+ const duplicateEmailSnapshot = {
381
+ content: {
382
+ id: "user2",
383
+ email: "john@example.com", // Same email
384
+ username: "jane_doe",
385
+ name: "Jane Doe",
386
+ },
387
+ };
388
+
389
+ const activeVersion = await lix.db
390
+ .selectFrom("active_version")
391
+ .select("version_id")
392
+ .executeTakeFirstOrThrow();
393
+
394
+ expect(() =>
395
+ validateStateMutation({
396
+ lix,
397
+ schema,
398
+ snapshot_content: duplicateEmailSnapshot.content,
399
+ operation: "insert",
400
+ version_id: activeVersion.version_id,
401
+ })
402
+ ).toThrowError("Unique constraint violation");
403
+
404
+ // Try to insert another user with same username (unique constraint violation)
405
+ const duplicateUsernameSnapshot = {
406
+ content: {
407
+ id: "user3",
408
+ email: "jane@example.com",
409
+ username: "john_doe", // Same username
410
+ name: "Jane Smith",
411
+ },
412
+ };
413
+
414
+ expect(() =>
415
+ validateStateMutation({
416
+ lix,
417
+ schema,
418
+ snapshot_content: duplicateUsernameSnapshot.content,
419
+ operation: "insert",
420
+ version_id: activeVersion.version_id,
421
+ })
422
+ ).toThrowError("Unique constraint violation");
423
+ });
424
+
425
+ test("handles composite unique constraints", async () => {
426
+ const lix = await openLix({});
427
+
428
+ const schema = {
429
+ type: "object",
430
+ "x-lix-version": "1.0",
431
+ "x-lix-key": "product",
432
+ "x-lix-primary-key": ["id"],
433
+ "x-lix-unique": [
434
+ ["category", "name"], // Composite unique constraint
435
+ ["sku"], // Single field unique constraint
436
+ ],
437
+ properties: {
438
+ id: { type: "string" },
439
+ category: { type: "string" },
440
+ name: { type: "string" },
441
+ sku: { type: "string" },
442
+ price: { type: "number" },
443
+ },
444
+ required: ["id", "category", "name", "sku", "price"],
445
+ additionalProperties: false,
446
+ } as const satisfies LixSchemaDefinition;
447
+
448
+ // Store the schema first
449
+ await lix.db.insertInto("stored_schema").values({ value: schema }).execute();
450
+
451
+ // Insert first product into state
452
+ await lix.db
453
+ .insertInto("state_all")
454
+ .values({
455
+ entity_id: "product1",
456
+ file_id: "file1",
457
+ schema_key: "product",
458
+ plugin_key: "test_plugin",
459
+ version_id: lix.db.selectFrom("active_version").select("version_id"),
460
+ snapshot_content: {
461
+ id: "product1",
462
+ category: "electronics",
463
+ name: "Laptop",
464
+ sku: "ELEC-LAP-001",
465
+ price: 999.99,
466
+ },
467
+ schema_version: "1.0",
468
+ })
469
+ .execute();
470
+
471
+ const activeVersion = await lix.db
472
+ .selectFrom("active_version")
473
+ .select("version_id")
474
+ .executeTakeFirstOrThrow();
475
+
476
+ // This should pass (different composite unique key)
477
+ expect(() =>
478
+ validateStateMutation({
479
+ lix,
480
+ schema,
481
+ snapshot_content: {
482
+ id: "product2",
483
+ category: "electronics",
484
+ name: "Desktop", // Different name in same category
485
+ sku: "ELEC-DES-001",
486
+ price: 1299.99,
487
+ },
488
+ operation: "insert",
489
+ version_id: activeVersion.version_id,
490
+ })
491
+ ).not.toThrowError();
492
+
493
+ // This should pass (same name in different category)
494
+ expect(() =>
495
+ validateStateMutation({
496
+ lix,
497
+ schema,
498
+ snapshot_content: {
499
+ id: "product3",
500
+ category: "furniture", // Different category
501
+ name: "Laptop", // Same name but different category
502
+ sku: "FURN-LAP-001",
503
+ price: 599.99,
504
+ },
505
+ operation: "insert",
506
+ version_id: activeVersion.version_id,
507
+ })
508
+ ).not.toThrowError();
509
+
510
+ // This should fail (same composite unique key: category + name)
511
+ expect(() =>
512
+ validateStateMutation({
513
+ lix,
514
+ schema,
515
+ snapshot_content: {
516
+ id: "product4",
517
+ category: "electronics",
518
+ name: "Laptop", // Same category + name combination
519
+ sku: "ELEC-LAP-002",
520
+ price: 899.99,
521
+ },
522
+ operation: "insert",
523
+ version_id: activeVersion.version_id,
524
+ })
525
+ ).toThrowError("Unique constraint violation");
526
+
527
+ // This should fail (same SKU)
528
+ expect(() =>
529
+ validateStateMutation({
530
+ lix,
531
+ schema,
532
+ snapshot_content: {
533
+ id: "product5",
534
+ category: "accessories",
535
+ name: "Mouse",
536
+ sku: "ELEC-LAP-001", // Same SKU
537
+ price: 29.99,
538
+ },
539
+ operation: "insert",
540
+ version_id: activeVersion.version_id,
541
+ })
542
+ ).toThrowError("Unique constraint violation");
543
+ });
544
+
545
+ test("passes when foreign key references exist", async () => {
546
+ const lix = await openLix({});
547
+
548
+ const userSchema = {
549
+ type: "object",
550
+ "x-lix-version": "1.0",
551
+ "x-lix-key": "user",
552
+ "x-lix-primary-key": ["id"],
553
+ properties: {
554
+ id: { type: "string" },
555
+ name: { type: "string" },
556
+ },
557
+ required: ["id", "name"],
558
+ additionalProperties: false,
559
+ } as const satisfies LixSchemaDefinition;
560
+
561
+ const postSchema = {
562
+ type: "object",
563
+ "x-lix-version": "1.0",
564
+ "x-lix-key": "post",
565
+ "x-lix-primary-key": ["id"],
566
+ "x-lix-foreign-keys": {
567
+ author_id: {
568
+ schemaKey: "user",
569
+ property: "id",
570
+ },
571
+ },
572
+ properties: {
573
+ id: { type: "string" },
574
+ author_id: { type: "string" },
575
+ title: { type: "string" },
576
+ },
577
+ required: ["id", "author_id", "title"],
578
+ additionalProperties: false,
579
+ } as const satisfies LixSchemaDefinition;
580
+
581
+ // Store schemas
582
+ await lix.db
583
+ .insertInto("stored_schema")
584
+ .values([{ value: userSchema }, { value: postSchema }])
585
+ .execute();
586
+
587
+ // Insert a user that will be referenced
588
+ await lix.db
589
+ .insertInto("state_all")
590
+ .values({
591
+ entity_id: "user1",
592
+ file_id: "file1",
593
+ schema_key: "user",
594
+ plugin_key: "test_plugin",
595
+ version_id: lix.db.selectFrom("active_version").select("version_id"),
596
+ snapshot_content: {
597
+ id: "user1",
598
+ name: "John Doe",
599
+ },
600
+ schema_version: "1.0",
601
+ })
602
+ .execute();
603
+
604
+ const activeVersion = await lix.db
605
+ .selectFrom("active_version")
606
+ .select("version_id")
607
+ .executeTakeFirstOrThrow();
608
+
609
+ // This should pass - foreign key reference exists
610
+ expect(() =>
611
+ validateStateMutation({
612
+ lix,
613
+ schema: postSchema,
614
+ snapshot_content: {
615
+ id: "post1",
616
+ author_id: "user1",
617
+ title: "My First Post",
618
+ },
619
+ operation: "insert",
620
+ version_id: activeVersion.version_id,
621
+ })
622
+ ).not.toThrowError();
623
+ });
624
+
625
+ test("throws when foreign key reference does not exist", async () => {
626
+ const lix = await openLix({});
627
+
628
+ const userSchema = {
629
+ type: "object",
630
+ "x-lix-version": "1.0",
631
+ "x-lix-key": "user",
632
+ "x-lix-primary-key": ["id"],
633
+ properties: {
634
+ id: { type: "string" },
635
+ name: { type: "string" },
636
+ },
637
+ required: ["id", "name"],
638
+ additionalProperties: false,
639
+ } as const satisfies LixSchemaDefinition;
640
+
641
+ const postSchema = {
642
+ type: "object",
643
+ "x-lix-version": "1.0",
644
+ "x-lix-key": "post",
645
+ "x-lix-primary-key": ["id"],
646
+ "x-lix-foreign-keys": {
647
+ author_id: {
648
+ schemaKey: "user",
649
+ property: "id",
650
+ },
651
+ },
652
+ properties: {
653
+ id: { type: "string" },
654
+ author_id: { type: "string" },
655
+ title: { type: "string" },
656
+ },
657
+ required: ["id", "author_id", "title"],
658
+ additionalProperties: false,
659
+ } as const satisfies LixSchemaDefinition;
660
+
661
+ // Store schemas
662
+ await lix.db
663
+ .insertInto("stored_schema")
664
+ .values([{ value: userSchema }, { value: postSchema }])
665
+ .execute();
666
+
667
+ const activeVersion = await lix.db
668
+ .selectFrom("active_version")
669
+ .select("version_id")
670
+ .executeTakeFirstOrThrow();
671
+
672
+ // This should fail - foreign key reference does not exist
673
+ expect(() =>
674
+ validateStateMutation({
675
+ lix,
676
+ schema: postSchema,
677
+ snapshot_content: {
678
+ id: "post1",
679
+ author_id: "nonexistent_user",
680
+ title: "My First Post",
681
+ },
682
+ operation: "insert",
683
+ version_id: activeVersion.version_id,
684
+ })
685
+ ).toThrowError("Foreign key constraint violation");
686
+ });
687
+
688
+ test("handles multiple foreign keys", async () => {
689
+ const lix = await openLix({});
690
+
691
+ const userSchema = {
692
+ type: "object",
693
+ "x-lix-version": "1.0",
694
+ "x-lix-key": "user",
695
+ "x-lix-primary-key": ["id"],
696
+ properties: {
697
+ id: { type: "string" },
698
+ name: { type: "string" },
699
+ },
700
+ required: ["id", "name"],
701
+ additionalProperties: false,
702
+ } as const satisfies LixSchemaDefinition;
703
+
704
+ const categorySchema = {
705
+ type: "object",
706
+ "x-lix-version": "1.0",
707
+ "x-lix-key": "category",
708
+ "x-lix-primary-key": ["id"],
709
+ properties: {
710
+ id: { type: "string" },
711
+ name: { type: "string" },
712
+ },
713
+ required: ["id", "name"],
714
+ additionalProperties: false,
715
+ } as const satisfies LixSchemaDefinition;
716
+
717
+ const postSchema = {
718
+ type: "object",
719
+ "x-lix-version": "1.0",
720
+ "x-lix-key": "post",
721
+ "x-lix-primary-key": ["id"],
722
+ "x-lix-foreign-keys": {
723
+ author_id: {
724
+ schemaKey: "user",
725
+ property: "id",
726
+ },
727
+ category_id: {
728
+ schemaKey: "category",
729
+ property: "id",
730
+ },
731
+ },
732
+ properties: {
733
+ id: { type: "string" },
734
+ author_id: { type: "string" },
735
+ category_id: { type: "string" },
736
+ title: { type: "string" },
737
+ },
738
+ required: ["id", "author_id", "category_id", "title"],
739
+ additionalProperties: false,
740
+ } as const satisfies LixSchemaDefinition;
741
+
742
+ // Store schemas
743
+ await lix.db
744
+ .insertInto("stored_schema")
745
+ .values([
746
+ { value: userSchema },
747
+ { value: categorySchema },
748
+ { value: postSchema },
749
+ ])
750
+ .execute();
751
+
752
+ // Insert referenced entities
753
+ await lix.db
754
+ .insertInto("state_all")
755
+ .values([
756
+ {
757
+ entity_id: "user1",
758
+ file_id: "file1",
759
+ schema_key: "user",
760
+ plugin_key: "test_plugin",
761
+ version_id: lix.db.selectFrom("active_version").select("version_id"),
762
+ snapshot_content: {
763
+ id: "user1",
764
+ name: "John Doe",
765
+ },
766
+ schema_version: "1.0",
767
+ },
768
+ {
769
+ entity_id: "category1",
770
+ file_id: "file1",
771
+ schema_key: "category",
772
+ plugin_key: "test_plugin",
773
+ version_id: lix.db.selectFrom("active_version").select("version_id"),
774
+ snapshot_content: {
775
+ id: "category1",
776
+ name: "Technology",
777
+ },
778
+ schema_version: "1.0",
779
+ },
780
+ ])
781
+ .execute();
782
+
783
+ const activeVersion = await lix.db
784
+ .selectFrom("active_version")
785
+ .select("version_id")
786
+ .executeTakeFirstOrThrow();
787
+
788
+ // This should pass - all foreign key references exist
789
+ expect(() =>
790
+ validateStateMutation({
791
+ lix,
792
+ schema: postSchema,
793
+ snapshot_content: {
794
+ id: "post1",
795
+ author_id: "user1",
796
+ category_id: "category1",
797
+ title: "My Tech Post",
798
+ },
799
+ operation: "insert",
800
+ version_id: activeVersion.version_id,
801
+ })
802
+ ).not.toThrowError();
803
+
804
+ // This should fail - category reference does not exist
805
+ expect(() =>
806
+ validateStateMutation({
807
+ lix,
808
+ schema: postSchema,
809
+ snapshot_content: {
810
+ id: "post2",
811
+ author_id: "user1",
812
+ category_id: "nonexistent_category",
813
+ title: "Another Post",
814
+ },
815
+ operation: "insert",
816
+ version_id: activeVersion.version_id,
817
+ })
818
+ ).toThrowError("Foreign key constraint violation");
819
+ });
820
+
821
+ test("allows null foreign key values", async () => {
822
+ const lix = await openLix({});
823
+
824
+ const userSchema = {
825
+ type: "object",
826
+ "x-lix-version": "1.0",
827
+ "x-lix-key": "user",
828
+ "x-lix-primary-key": ["id"],
829
+ properties: {
830
+ id: { type: "string" },
831
+ name: { type: "string" },
832
+ },
833
+ required: ["id", "name"],
834
+ additionalProperties: false,
835
+ } as const satisfies LixSchemaDefinition;
836
+
837
+ const postSchema = {
838
+ type: "object",
839
+ "x-lix-version": "1.0",
840
+ "x-lix-key": "post",
841
+ "x-lix-primary-key": ["id"],
842
+ "x-lix-foreign-keys": {
843
+ author_id: {
844
+ schemaKey: "user",
845
+ property: "id",
846
+ },
847
+ },
848
+ properties: {
849
+ id: { type: "string" },
850
+ author_id: { type: ["string", "null"] },
851
+ title: { type: "string" },
852
+ },
853
+ required: ["id", "title"],
854
+ additionalProperties: false,
855
+ } as const satisfies LixSchemaDefinition;
856
+
857
+ // Store schemas
858
+ await lix.db
859
+ .insertInto("stored_schema")
860
+ .values([{ value: userSchema }, { value: postSchema }])
861
+ .execute();
862
+
863
+ const activeVersion = await lix.db
864
+ .selectFrom("active_version")
865
+ .select("version_id")
866
+ .executeTakeFirstOrThrow();
867
+
868
+ // This should pass - null foreign key is allowed
869
+ expect(() =>
870
+ validateStateMutation({
871
+ lix,
872
+ schema: postSchema,
873
+ snapshot_content: {
874
+ id: "post1",
875
+ author_id: null,
876
+ title: "Anonymous Post",
877
+ },
878
+ operation: "insert",
879
+ version_id: activeVersion.version_id,
880
+ })
881
+ ).not.toThrowError();
882
+
883
+ // This should also pass - undefined foreign key (when not required)
884
+ expect(() =>
885
+ validateStateMutation({
886
+ lix,
887
+ schema: postSchema,
888
+ snapshot_content: {
889
+ id: "post2",
890
+ title: "Another Anonymous Post",
891
+ },
892
+ operation: "insert",
893
+ version_id: activeVersion.version_id,
894
+ })
895
+ ).not.toThrowError();
896
+ });
897
+
898
+ test("foreign key referencing real SQL table (change.id)", async () => {
899
+ const lix = await openLix({});
900
+
901
+ // Insert a real change record into the change table
902
+ await lix.db
903
+ // @ts-expect-error - internal_snapshot is not a public table
904
+ .insertInto("internal_snapshot")
905
+ .values({
906
+ id: "snap1",
907
+ content: sql`jsonb(${JSON.stringify({ id: "entity1" })})`,
908
+ })
909
+ .execute();
910
+
911
+ await lix.db
912
+ // @ts-expect-error - internal_change is not a public table
913
+ .insertInto("internal_change")
914
+ .values({
915
+ id: "change1",
916
+ entity_id: "entity1",
917
+ plugin_key: "test_plugin",
918
+ schema_key: "test_schema",
919
+ schema_version: "1.0",
920
+ file_id: "file1",
921
+ snapshot_id: "snap1",
922
+ })
923
+ .execute();
924
+
925
+ const changeSetElementSchema = {
926
+ type: "object",
927
+ "x-lix-version": "1.0",
928
+ "x-lix-key": "change_set_element_test",
929
+ "x-lix-foreign-keys": {
930
+ change_id: {
931
+ schemaKey: "lix_change",
932
+ property: "id",
933
+ },
934
+ },
935
+ properties: {
936
+ id: { type: "string" },
937
+ change_id: { type: "string" },
938
+ },
939
+ required: ["id", "change_id"],
940
+ additionalProperties: false,
941
+ } as const satisfies LixSchemaDefinition;
942
+
943
+ const activeVersion = await lix.db
944
+ .selectFrom("active_version")
945
+ .select("version_id")
946
+ .executeTakeFirstOrThrow();
947
+
948
+ // This should pass - foreign key references existing change record
949
+ expect(() =>
950
+ validateStateMutation({
951
+ lix,
952
+ schema: changeSetElementSchema,
953
+ snapshot_content: {
954
+ id: "element1",
955
+ change_id: "change1",
956
+ },
957
+ operation: "insert",
958
+ version_id: activeVersion.version_id,
959
+ })
960
+ ).not.toThrowError();
961
+
962
+ // This should fail - foreign key references non-existent change
963
+ expect(() =>
964
+ validateStateMutation({
965
+ lix,
966
+ schema: changeSetElementSchema,
967
+ snapshot_content: {
968
+ id: "element2",
969
+ change_id: "nonexistent_change",
970
+ },
971
+ operation: "insert",
972
+ version_id: activeVersion.version_id,
973
+ })
974
+ ).toThrowError("Foreign key constraint violation");
975
+ });
976
+
977
+ test("allows updates with same primary key", async () => {
978
+ const lix = await openLix({});
979
+
980
+ const activeVersion = await lix.db
981
+ .selectFrom("active_version")
982
+ .select("version_id")
983
+ .executeTakeFirstOrThrow();
984
+
985
+ const schema = {
986
+ type: "object",
987
+ "x-lix-version": "1.0",
988
+ "x-lix-key": "user",
989
+ "x-lix-primary-key": ["id"],
990
+ properties: {
991
+ id: { type: "string" },
992
+ name: { type: "string" },
993
+ },
994
+ required: ["id", "name"],
995
+ additionalProperties: false,
996
+ } as const satisfies LixSchemaDefinition;
997
+
998
+ // Store the schema first
999
+ await lix.db.insertInto("stored_schema").values({ value: schema }).execute();
1000
+
1001
+ // Insert initial user
1002
+ await lix.db
1003
+ .insertInto("state_all")
1004
+ .values({
1005
+ entity_id: "user1",
1006
+ file_id: "file1",
1007
+ schema_key: "user",
1008
+ plugin_key: "test_plugin",
1009
+ version_id: lix.db.selectFrom("active_version").select("version_id"),
1010
+ snapshot_content: { id: "user1", name: "John Doe" },
1011
+ schema_version: "1.0",
1012
+ })
1013
+ .execute();
1014
+
1015
+ // This should pass - updating existing record with same primary key
1016
+ expect(() =>
1017
+ validateStateMutation({
1018
+ lix,
1019
+ schema,
1020
+ snapshot_content: {
1021
+ id: "user1", // Same primary key
1022
+ name: "John Smith", // Different data
1023
+ },
1024
+ operation: "update",
1025
+ entity_id: "user1",
1026
+ version_id: activeVersion.version_id,
1027
+ })
1028
+ ).not.toThrowError();
1029
+ });
1030
+
1031
+ test("unique constraints are validated per version, not globally", async () => {
1032
+ const lix = await openLix({});
1033
+
1034
+ const schema = {
1035
+ type: "object",
1036
+ "x-lix-version": "1.0",
1037
+ "x-lix-key": "file",
1038
+ "x-lix-primary-key": ["id"],
1039
+ "x-lix-unique": [["path"]], // Unique path constraint
1040
+ properties: {
1041
+ id: { type: "string" },
1042
+ path: { type: "string" },
1043
+ content: { type: "string" },
1044
+ },
1045
+ required: ["id", "path", "content"],
1046
+ additionalProperties: false,
1047
+ } as const satisfies LixSchemaDefinition;
1048
+
1049
+ // Store the schema first
1050
+ await lix.db.insertInto("stored_schema").values({ value: schema }).execute();
1051
+
1052
+ // Create two different versions
1053
+ await createVersion({
1054
+ lix,
1055
+ id: "version0",
1056
+ });
1057
+
1058
+ await createVersion({
1059
+ lix,
1060
+ id: "version1",
1061
+ });
1062
+ // Insert file with path "/app.js" in version1
1063
+ await lix.db
1064
+ .insertInto("state_all")
1065
+ .values({
1066
+ entity_id: "file1",
1067
+ file_id: "file1",
1068
+ schema_key: "file",
1069
+ plugin_key: "test_plugin",
1070
+ version_id: "version0",
1071
+ snapshot_content: {
1072
+ id: "file1",
1073
+ path: "/app.js",
1074
+ content: "console.log('version 0');",
1075
+ },
1076
+ schema_version: "1.0",
1077
+ })
1078
+ .execute();
1079
+
1080
+ // This should pass - same path in different version should be allowed
1081
+ expect(() =>
1082
+ validateStateMutation({
1083
+ lix,
1084
+ schema,
1085
+ snapshot_content: {
1086
+ id: "file2",
1087
+ path: "/app.js", // Same path but different version
1088
+ content: "console.log('version 1');",
1089
+ },
1090
+ operation: "insert",
1091
+ version_id: "version1",
1092
+ })
1093
+ ).not.toThrowError();
1094
+
1095
+ // This should fail - same path in same version
1096
+ expect(() =>
1097
+ validateStateMutation({
1098
+ lix,
1099
+ schema,
1100
+ snapshot_content: {
1101
+ id: "file3",
1102
+ path: "/app.js", // Same path and same version
1103
+ content: "console.log('duplicate');",
1104
+ },
1105
+ operation: "insert",
1106
+ version_id: "version0",
1107
+ })
1108
+ ).toThrowError("Unique constraint violation");
1109
+ });
1110
+
1111
+ test("throws when version_id is not provided", async () => {
1112
+ const lix = await openLix({});
1113
+
1114
+ const schema = {
1115
+ type: "object",
1116
+ "x-lix-version": "1.0",
1117
+ "x-lix-key": "user",
1118
+ "x-lix-primary-key": ["id"],
1119
+ properties: {
1120
+ id: { type: "string" },
1121
+ name: { type: "string" },
1122
+ },
1123
+ required: ["id", "name"],
1124
+ additionalProperties: false,
1125
+ } as const satisfies LixSchemaDefinition;
1126
+
1127
+ expect(() =>
1128
+ validateStateMutation({
1129
+ lix,
1130
+ schema,
1131
+ snapshot_content: { id: "user1", name: "John" },
1132
+ operation: "insert",
1133
+ // @ts-expect-error - version_id is required but missing
1134
+ version_id: undefined,
1135
+ })
1136
+ ).toThrowError("version_id is required");
1137
+ });
1138
+
1139
+ test("throws when referenced version does not exist", async () => {
1140
+ const lix = await openLix({});
1141
+
1142
+ const schema = {
1143
+ type: "object",
1144
+ "x-lix-version": "1.0",
1145
+ "x-lix-key": "user",
1146
+ "x-lix-primary-key": ["id"],
1147
+ properties: {
1148
+ id: { type: "string" },
1149
+ name: { type: "string" },
1150
+ },
1151
+ required: ["id", "name"],
1152
+ additionalProperties: false,
1153
+ } as const satisfies LixSchemaDefinition;
1154
+
1155
+ expect(() =>
1156
+ validateStateMutation({
1157
+ lix,
1158
+ schema,
1159
+ snapshot_content: { id: "user1", name: "John" },
1160
+ operation: "insert",
1161
+ version_id: "nonexistent_version",
1162
+ })
1163
+ ).toThrowError("Version with id 'nonexistent_version' does not exist");
1164
+ });
1165
+
1166
+ test("passes when version_id is provided and version exists", async () => {
1167
+ const lix = await openLix({});
1168
+
1169
+ const schema = {
1170
+ type: "object",
1171
+ "x-lix-version": "1.0",
1172
+ "x-lix-key": "user",
1173
+ "x-lix-primary-key": ["id"],
1174
+ properties: {
1175
+ id: { type: "string" },
1176
+ name: { type: "string" },
1177
+ },
1178
+ required: ["id", "name"],
1179
+ additionalProperties: false,
1180
+ } as const satisfies LixSchemaDefinition;
1181
+
1182
+ const activeVersion = await lix.db
1183
+ .selectFrom("active_version")
1184
+ .select("version_id")
1185
+ .executeTakeFirstOrThrow();
1186
+
1187
+ expect(() =>
1188
+ validateStateMutation({
1189
+ lix,
1190
+ schema,
1191
+ snapshot_content: { id: "user1", name: "John" },
1192
+ operation: "insert",
1193
+ version_id: activeVersion.version_id,
1194
+ })
1195
+ ).not.toThrowError();
1196
+ });
1197
+
1198
+ test("should prevent deletion when foreign keys reference the entity", async () => {
1199
+ const lix = await openLix({});
1200
+
1201
+ const userSchema = {
1202
+ type: "object",
1203
+ "x-lix-version": "1.0",
1204
+ "x-lix-key": "user",
1205
+ "x-lix-primary-key": ["id"],
1206
+ properties: {
1207
+ id: { type: "string" },
1208
+ name: { type: "string" },
1209
+ },
1210
+ required: ["id", "name"],
1211
+ additionalProperties: false,
1212
+ } as const satisfies LixSchemaDefinition;
1213
+
1214
+ const postSchema = {
1215
+ type: "object",
1216
+ "x-lix-version": "1.0",
1217
+ "x-lix-key": "post",
1218
+ "x-lix-primary-key": ["id"],
1219
+ "x-lix-foreign-keys": {
1220
+ author_id: {
1221
+ schemaKey: "user",
1222
+ property: "id",
1223
+ },
1224
+ },
1225
+ properties: {
1226
+ id: { type: "string" },
1227
+ author_id: { type: "string" },
1228
+ title: { type: "string" },
1229
+ },
1230
+ required: ["id", "author_id", "title"],
1231
+ additionalProperties: false,
1232
+ } as const satisfies LixSchemaDefinition;
1233
+
1234
+ // Store schemas
1235
+ await lix.db
1236
+ .insertInto("stored_schema")
1237
+ .values([{ value: userSchema }, { value: postSchema }])
1238
+ .execute();
1239
+
1240
+ const activeVersion = await lix.db
1241
+ .selectFrom("active_version")
1242
+ .select("version_id")
1243
+ .executeTakeFirstOrThrow();
1244
+
1245
+ // Insert a user that will be referenced
1246
+ await lix.db
1247
+ .insertInto("state_all")
1248
+ .values({
1249
+ entity_id: "user1",
1250
+ file_id: "file1",
1251
+ schema_key: "user",
1252
+ plugin_key: "test_plugin",
1253
+ version_id: activeVersion.version_id,
1254
+ snapshot_content: {
1255
+ id: "user1",
1256
+ name: "John Doe",
1257
+ },
1258
+ schema_version: "1.0",
1259
+ })
1260
+ .execute();
1261
+
1262
+ // Insert a post that references the user
1263
+ await lix.db
1264
+ .insertInto("state_all")
1265
+ .values({
1266
+ entity_id: "post1",
1267
+ file_id: "file1",
1268
+ schema_key: "post",
1269
+ plugin_key: "test_plugin",
1270
+ version_id: activeVersion.version_id,
1271
+ snapshot_content: {
1272
+ id: "post1",
1273
+ author_id: "user1",
1274
+ title: "My First Post",
1275
+ },
1276
+ schema_version: "1.0",
1277
+ })
1278
+ .execute();
1279
+
1280
+ // This should fail - cannot delete user because post references it
1281
+ expect(() =>
1282
+ validateStateMutation({
1283
+ lix,
1284
+ schema: userSchema,
1285
+ snapshot_content: {}, // Not used for delete operations
1286
+ operation: "delete",
1287
+ entity_id: "user1",
1288
+ version_id: activeVersion.version_id,
1289
+ })
1290
+ ).toThrowError(
1291
+ /Foreign key constraint violation.*referenced by.*post.*author_id/i
1292
+ );
1293
+ });
1294
+
1295
+ test("should allow deletion when no foreign keys reference the entity", async () => {
1296
+ const lix = await openLix({});
1297
+
1298
+ const userSchema = {
1299
+ type: "object",
1300
+ "x-lix-version": "1.0",
1301
+ "x-lix-key": "user",
1302
+ "x-lix-primary-key": ["id"],
1303
+ properties: {
1304
+ id: { type: "string" },
1305
+ name: { type: "string" },
1306
+ },
1307
+ required: ["id", "name"],
1308
+ additionalProperties: false,
1309
+ } as const satisfies LixSchemaDefinition;
1310
+
1311
+ // Store schema
1312
+ await lix.db
1313
+ .insertInto("stored_schema")
1314
+ .values({ value: userSchema })
1315
+ .execute();
1316
+
1317
+ const activeVersion = await lix.db
1318
+ .selectFrom("active_version")
1319
+ .select("version_id")
1320
+ .executeTakeFirstOrThrow();
1321
+
1322
+ // Insert a user with no references
1323
+ await lix.db
1324
+ .insertInto("state_all")
1325
+ .values({
1326
+ entity_id: "user1",
1327
+ file_id: "file1",
1328
+ schema_key: "user",
1329
+ plugin_key: "test_plugin",
1330
+ version_id: activeVersion.version_id,
1331
+ snapshot_content: {
1332
+ id: "user1",
1333
+ name: "John Doe",
1334
+ },
1335
+ schema_version: "1.0",
1336
+ })
1337
+ .execute();
1338
+
1339
+ // This should pass - no foreign keys reference this user
1340
+ expect(() =>
1341
+ validateStateMutation({
1342
+ lix,
1343
+ schema: userSchema,
1344
+ snapshot_content: {}, // Not used for delete operations
1345
+ operation: "delete",
1346
+ entity_id: "user1",
1347
+ version_id: activeVersion.version_id,
1348
+ })
1349
+ ).not.toThrowError();
1350
+ });
1351
+
1352
+ test("should throw when deleting non-existent entity", async () => {
1353
+ const lix = await openLix({});
1354
+
1355
+ const userSchema = {
1356
+ type: "object",
1357
+ "x-lix-version": "1.0",
1358
+ "x-lix-key": "user",
1359
+ "x-lix-primary-key": ["id"],
1360
+ properties: {
1361
+ id: { type: "string" },
1362
+ name: { type: "string" },
1363
+ },
1364
+ required: ["id", "name"],
1365
+ additionalProperties: false,
1366
+ } as const satisfies LixSchemaDefinition;
1367
+
1368
+ const activeVersion = await lix.db
1369
+ .selectFrom("active_version")
1370
+ .select("version_id")
1371
+ .executeTakeFirstOrThrow();
1372
+
1373
+ // This should fail - entity does not exist
1374
+ expect(() =>
1375
+ validateStateMutation({
1376
+ lix,
1377
+ schema: userSchema,
1378
+ snapshot_content: {},
1379
+ operation: "delete",
1380
+ entity_id: "nonexistent_user",
1381
+ version_id: activeVersion.version_id,
1382
+ })
1383
+ ).toThrowError(/Entity deletion failed/);
1384
+ });
1385
+
1386
+ test("should throw when entity_id is missing for delete operations", async () => {
1387
+ const lix = await openLix({});
1388
+
1389
+ const userSchema = {
1390
+ type: "object",
1391
+ "x-lix-version": "1.0",
1392
+ "x-lix-key": "user",
1393
+ "x-lix-primary-key": ["id"],
1394
+ properties: {
1395
+ id: { type: "string" },
1396
+ name: { type: "string" },
1397
+ },
1398
+ required: ["id", "name"],
1399
+ additionalProperties: false,
1400
+ } as const satisfies LixSchemaDefinition;
1401
+
1402
+ const activeVersion = await lix.db
1403
+ .selectFrom("active_version")
1404
+ .select("version_id")
1405
+ .executeTakeFirstOrThrow();
1406
+
1407
+ // This should fail - entity_id is required for delete
1408
+ expect(() =>
1409
+ validateStateMutation({
1410
+ lix,
1411
+ schema: userSchema,
1412
+ snapshot_content: {},
1413
+ operation: "delete",
1414
+ // entity_id is missing
1415
+ version_id: activeVersion.version_id,
1416
+ })
1417
+ ).toThrowError("entity_id is required for delete operations");
1418
+ });
1419
+
1420
+ test("should handle deletion validation for change sets referenced by versions", async () => {
1421
+ const lix = await openLix({});
1422
+
1423
+ // Create a change set
1424
+ await lix.db
1425
+ .insertInto("change_set_all")
1426
+ .values({ id: "cs_referenced", lixcol_version_id: "global" })
1427
+ .execute();
1428
+
1429
+ // Create a version that references the change set
1430
+ await lix.db
1431
+ .insertInto("version")
1432
+ .values({
1433
+ id: "v1",
1434
+ name: "test_version",
1435
+ change_set_id: "cs_referenced",
1436
+ working_change_set_id: "cs_referenced",
1437
+ })
1438
+ .execute();
1439
+
1440
+ // const activeVersion = await lix.db
1441
+ // .selectFrom("active_version")
1442
+ // .select("version_id")
1443
+ // .executeTakeFirstOrThrow();
1444
+
1445
+ // Get the change set schema
1446
+ const changeSetSchema = await lix.db
1447
+ .selectFrom("stored_schema")
1448
+ .select("value")
1449
+ .where("key", "=", "lix_change_set")
1450
+ .executeTakeFirstOrThrow();
1451
+
1452
+ // This should fail - cannot delete change set because version references it
1453
+ expect(() =>
1454
+ validateStateMutation({
1455
+ lix,
1456
+ schema: changeSetSchema.value as LixSchemaDefinition,
1457
+ snapshot_content: {},
1458
+ operation: "delete",
1459
+ entity_id: "cs_referenced",
1460
+ version_id: "global",
1461
+ })
1462
+ ).toThrowError(
1463
+ /Foreign key constraint violation.*Cannot delete entity.*referenced by.*lix_version/i
1464
+ );
1465
+ });
1466
+
1467
+ test("should parse JSON object properties before validation", async () => {
1468
+ const lix = await openLix({});
1469
+
1470
+ // Define a schema with an object property
1471
+ const documentSchema = {
1472
+ type: "object",
1473
+ "x-lix-version": "1.0",
1474
+ "x-lix-key": "document",
1475
+ "x-lix-primary-key": ["id"],
1476
+ properties: {
1477
+ id: { type: "string" },
1478
+ title: { type: "string" },
1479
+ body: {
1480
+ type: "object",
1481
+ properties: {
1482
+ type: { type: "string" },
1483
+ content: { type: "array" },
1484
+ },
1485
+ required: ["type", "content"],
1486
+ },
1487
+ },
1488
+ required: ["id", "title", "body"],
1489
+ additionalProperties: false,
1490
+ } as const satisfies LixSchemaDefinition;
1491
+
1492
+ // Store the schema
1493
+ await lix.db
1494
+ .insertInto("stored_schema")
1495
+ .values({ value: documentSchema })
1496
+ .execute();
1497
+
1498
+ const activeVersion = await lix.db
1499
+ .selectFrom("active_version")
1500
+ .select("version_id")
1501
+ .executeTakeFirstOrThrow();
1502
+
1503
+ // Test with valid JSON object - this should pass
1504
+ const validSnapshotContent = {
1505
+ id: "doc1",
1506
+ title: "Test Document",
1507
+ body: JSON.stringify({
1508
+ type: "zettel_doc",
1509
+ content: [
1510
+ {
1511
+ type: "zettel_text_block",
1512
+ zettel_key: "test_key",
1513
+ style: "zettel_normal",
1514
+ children: [],
1515
+ },
1516
+ ],
1517
+ }),
1518
+ };
1519
+
1520
+ expect(() =>
1521
+ validateStateMutation({
1522
+ lix,
1523
+ schema: documentSchema,
1524
+ snapshot_content: validSnapshotContent,
1525
+ operation: "insert",
1526
+ version_id: activeVersion.version_id,
1527
+ })
1528
+ ).not.toThrowError();
1529
+
1530
+ // Test with invalid JSON object - this should fail
1531
+ const invalidSnapshotContent = {
1532
+ id: "doc2",
1533
+ title: "Invalid Document",
1534
+ body: JSON.stringify({
1535
+ type: "invalid_type", // Missing required 'content' property
1536
+ }),
1537
+ };
1538
+
1539
+ expect(() =>
1540
+ validateStateMutation({
1541
+ lix,
1542
+ schema: documentSchema,
1543
+ snapshot_content: invalidSnapshotContent,
1544
+ operation: "insert",
1545
+ version_id: activeVersion.version_id,
1546
+ })
1547
+ ).toThrowError(/body.*must have required property.*content/);
1548
+
1549
+ // Test with malformed JSON string - this should fail
1550
+ const malformedSnapshotContent = {
1551
+ id: "doc3",
1552
+ title: "Malformed Document",
1553
+ body: "{ invalid json",
1554
+ };
1555
+
1556
+ expect(() =>
1557
+ validateStateMutation({
1558
+ lix,
1559
+ schema: documentSchema,
1560
+ snapshot_content: malformedSnapshotContent,
1561
+ operation: "insert",
1562
+ version_id: activeVersion.version_id,
1563
+ })
1564
+ ).toThrowError(/Invalid JSON in property 'body'/);
1565
+ });
1566
+
1567
+ test("foreign key validation should fail when referenced entity exists in different non-inheriting version", async () => {
1568
+ const lix = await openLix({});
1569
+
1570
+ // Mock schema for a "User" entity
1571
+ const userSchema = {
1572
+ "x-lix-key": "mock_user",
1573
+ "x-lix-version": "1.0",
1574
+ "x-lix-primary-key": ["id"],
1575
+ type: "object",
1576
+ properties: {
1577
+ id: { type: "string" },
1578
+ name: { type: "string" },
1579
+ },
1580
+ required: ["id", "name"],
1581
+ additionalProperties: false,
1582
+ } as const satisfies LixSchemaDefinition;
1583
+
1584
+ // Mock schema for a "Post" entity that references User
1585
+ const postSchema = {
1586
+ "x-lix-key": "mock_post",
1587
+ "x-lix-version": "1.0",
1588
+ "x-lix-primary-key": ["id"],
1589
+ "x-lix-foreign-keys": {
1590
+ author_id: {
1591
+ schemaKey: "mock_user",
1592
+ property: "id",
1593
+ },
1594
+ },
1595
+ type: "object",
1596
+ properties: {
1597
+ id: { type: "string" },
1598
+ title: { type: "string" },
1599
+ author_id: { type: "string" },
1600
+ },
1601
+ required: ["id", "title", "author_id"],
1602
+ additionalProperties: false,
1603
+ } as const satisfies LixSchemaDefinition;
1604
+
1605
+ // Register our mock schemas
1606
+ await lix.db
1607
+ .insertInto("stored_schema")
1608
+ .values([{ value: userSchema }, { value: postSchema }])
1609
+ .execute();
1610
+
1611
+ // Create two separate versions that don't inherit from each other
1612
+ const versionA = await createVersion({
1613
+ lix,
1614
+ name: "version-a",
1615
+ });
1616
+
1617
+ const versionB = await createVersion({
1618
+ lix,
1619
+ name: "version-b",
1620
+ });
1621
+
1622
+ // Verify they don't inherit from each other
1623
+ // Both should inherit from global, but not from each other
1624
+ expect(versionA.inherits_from_version_id).toBe("global");
1625
+ expect(versionB.inherits_from_version_id).toBe("global");
1626
+
1627
+ // Create a user in version A
1628
+ await lix.db
1629
+ .insertInto("state_all")
1630
+ .values({
1631
+ entity_id: "user-1",
1632
+ schema_key: "mock_user",
1633
+ file_id: "test",
1634
+ plugin_key: "test_plugin",
1635
+ snapshot_content: {
1636
+ id: "user-1",
1637
+ name: "Alice",
1638
+ },
1639
+ schema_version: "1.0",
1640
+ version_id: versionA.id,
1641
+ })
1642
+ .execute();
1643
+
1644
+ // BUG: This should FAIL because user-1 doesn't exist in version B's context
1645
+ // but the current foreign key validation logic will find user-1 in version A
1646
+ // and incorrectly allow this validation to succeed
1647
+ expect(() =>
1648
+ validateStateMutation({
1649
+ lix,
1650
+ schema: postSchema,
1651
+ snapshot_content: {
1652
+ id: "post-1",
1653
+ title: "My Post",
1654
+ author_id: "user-1", // References user-1 which only exists in version A
1655
+ },
1656
+ operation: "insert",
1657
+ version_id: versionB.id,
1658
+ })
1659
+ ).toThrow(/Foreign key constraint violation.*mock_user.*user-1/);
1660
+
1661
+ // Verify that user-1 indeed doesn't exist in version B's context
1662
+ const userInVersionB = await lix.db
1663
+ .selectFrom("state_all")
1664
+ .where("entity_id", "=", "user-1")
1665
+ .where("schema_key", "=", "mock_user")
1666
+ .where("version_id", "=", versionB.id)
1667
+ .selectAll()
1668
+ .execute();
1669
+
1670
+ expect(userInVersionB).toHaveLength(0);
1671
+
1672
+ // But verify it does exist in version A
1673
+ const userInVersionA = await lix.db
1674
+ .selectFrom("state_all")
1675
+ .where("entity_id", "=", "user-1")
1676
+ .where("schema_key", "=", "mock_user")
1677
+ .where("version_id", "=", versionA.id)
1678
+ .selectAll()
1679
+ .execute();
1680
+
1681
+ expect(userInVersionA).toHaveLength(1);
1682
+ });
1683
+
1684
+ test("should allow self-referential foreign keys", async () => {
1685
+ const lix = await openLix({});
1686
+
1687
+ // Define a schema with self-referential foreign key (like version inheritance)
1688
+ const versionSchema = {
1689
+ type: "object",
1690
+ "x-lix-version": "1.0",
1691
+ "x-lix-key": "mock_version",
1692
+ "x-lix-primary-key": ["id"],
1693
+ "x-lix-foreign-keys": {
1694
+ inherits_from_version_id: {
1695
+ schemaKey: "mock_version", // Self-referential foreign key
1696
+ property: "id",
1697
+ },
1698
+ },
1699
+ properties: {
1700
+ id: { type: "string" },
1701
+ name: { type: "string" },
1702
+ inherits_from_version_id: { type: ["string", "null"] },
1703
+ },
1704
+ required: ["id", "name"],
1705
+ additionalProperties: false,
1706
+ } as const satisfies LixSchemaDefinition;
1707
+
1708
+ // Store the schema
1709
+ await lix.db
1710
+ .insertInto("stored_schema")
1711
+ .values({ value: versionSchema })
1712
+ .execute();
1713
+
1714
+ const activeVersion = await lix.db
1715
+ .selectFrom("active_version")
1716
+ .select("version_id")
1717
+ .executeTakeFirstOrThrow();
1718
+
1719
+ // Insert a parent version first (with null inheritance)
1720
+ await lix.db
1721
+ .insertInto("state_all")
1722
+ .values({
1723
+ entity_id: "version0",
1724
+ file_id: "file1",
1725
+ schema_key: "mock_version",
1726
+ plugin_key: "test_plugin",
1727
+ version_id: activeVersion.version_id,
1728
+ snapshot_content: {
1729
+ id: "version0",
1730
+ name: "version0",
1731
+ inherits_from_version_id: null,
1732
+ },
1733
+ schema_version: "1.0",
1734
+ })
1735
+ .execute();
1736
+
1737
+ // This should pass - child version referencing parent version (valid self-referential FK)
1738
+ expect(() =>
1739
+ validateStateMutation({
1740
+ lix,
1741
+ schema: versionSchema,
1742
+ snapshot_content: {
1743
+ id: "version1",
1744
+ name: "version1",
1745
+ inherits_from_version_id: "version0", // References another entity in same schema
1746
+ },
1747
+ operation: "insert",
1748
+ version_id: activeVersion.version_id,
1749
+ })
1750
+ ).not.toThrowError();
1751
+
1752
+ // This should also pass - version with null inheritance (no foreign key constraint)
1753
+ expect(() =>
1754
+ validateStateMutation({
1755
+ lix,
1756
+ schema: versionSchema,
1757
+ snapshot_content: {
1758
+ id: "version2",
1759
+ name: "version2",
1760
+ inherits_from_version_id: null, // No foreign key reference
1761
+ },
1762
+ operation: "insert",
1763
+ version_id: activeVersion.version_id,
1764
+ })
1765
+ ).not.toThrowError();
1766
+
1767
+ // This should fail - referencing non-existent version
1768
+ expect(() =>
1769
+ validateStateMutation({
1770
+ lix,
1771
+ schema: versionSchema,
1772
+ snapshot_content: {
1773
+ id: "version3",
1774
+ name: "version3",
1775
+ inherits_from_version_id: "nonexistent_version",
1776
+ },
1777
+ operation: "insert",
1778
+ version_id: activeVersion.version_id,
1779
+ })
1780
+ ).toThrowError("Foreign key constraint violation");
1781
+ });
1782
+
1783
+ test("should allow self-referential foreign keys for update operations", async () => {
1784
+ const lix = await openLix({});
1785
+
1786
+ // Define a schema with self-referential foreign key
1787
+ const versionSchema = {
1788
+ type: "object",
1789
+ "x-lix-version": "1.0",
1790
+ "x-lix-key": "mock_version",
1791
+ "x-lix-primary-key": ["id"],
1792
+ "x-lix-foreign-keys": {
1793
+ inherits_from_version_id: {
1794
+ schemaKey: "mock_version",
1795
+ property: "id",
1796
+ },
1797
+ },
1798
+ properties: {
1799
+ id: { type: "string" },
1800
+ name: { type: "string" },
1801
+ inherits_from_version_id: { type: ["string", "null"] },
1802
+ },
1803
+ required: ["id", "name"],
1804
+ additionalProperties: false,
1805
+ } as const satisfies LixSchemaDefinition;
1806
+
1807
+ // Store the schema
1808
+ await lix.db
1809
+ .insertInto("stored_schema")
1810
+ .values({ value: versionSchema })
1811
+ .execute();
1812
+
1813
+ const activeVersion = await lix.db
1814
+ .selectFrom("active_version")
1815
+ .select("version_id")
1816
+ .executeTakeFirstOrThrow();
1817
+
1818
+ // Insert initial versions
1819
+ await lix.db
1820
+ .insertInto("state_all")
1821
+ .values([
1822
+ {
1823
+ entity_id: "version0",
1824
+ file_id: "file1",
1825
+ schema_key: "mock_version",
1826
+ plugin_key: "test_plugin",
1827
+ version_id: activeVersion.version_id,
1828
+ snapshot_content: {
1829
+ id: "version0",
1830
+ name: "version0",
1831
+ inherits_from_version_id: null,
1832
+ },
1833
+ schema_version: "1.0",
1834
+ },
1835
+ {
1836
+ entity_id: "version1",
1837
+ file_id: "file1",
1838
+ schema_key: "mock_version",
1839
+ plugin_key: "test_plugin",
1840
+ version_id: activeVersion.version_id,
1841
+ snapshot_content: {
1842
+ id: "version1",
1843
+ name: "version1",
1844
+ inherits_from_version_id: "version0",
1845
+ },
1846
+ schema_version: "1.0",
1847
+ },
1848
+ ])
1849
+ .execute();
1850
+
1851
+ // This should pass - updating to reference a different valid version
1852
+ expect(() =>
1853
+ validateStateMutation({
1854
+ lix,
1855
+ schema: versionSchema,
1856
+ snapshot_content: {
1857
+ id: "version1",
1858
+ name: "version1_updated",
1859
+ inherits_from_version_id: null, // Change from version0 to null
1860
+ },
1861
+ operation: "update",
1862
+ entity_id: "version1",
1863
+ version_id: activeVersion.version_id,
1864
+ })
1865
+ ).not.toThrowError();
1866
+
1867
+ // This should fail - updating to reference non-existent version
1868
+ expect(() =>
1869
+ validateStateMutation({
1870
+ lix,
1871
+ schema: versionSchema,
1872
+ snapshot_content: {
1873
+ id: "version1",
1874
+ name: "version1_updated",
1875
+ inherits_from_version_id: "nonexistent_version",
1876
+ },
1877
+ operation: "update",
1878
+ entity_id: "version1",
1879
+ version_id: activeVersion.version_id,
1880
+ })
1881
+ ).toThrowError("Foreign key constraint violation");
1882
+ });
1883
+
1884
+ test("should prevent deletion when self-referential foreign keys reference the entity", async () => {
1885
+ const lix = await openLix({});
1886
+
1887
+ // Define a schema with self-referential foreign key
1888
+ const versionSchema = {
1889
+ type: "object",
1890
+ "x-lix-version": "1.0",
1891
+ "x-lix-key": "mock_version",
1892
+ "x-lix-primary-key": ["id"],
1893
+ "x-lix-foreign-keys": {
1894
+ inherits_from_version_id: {
1895
+ schemaKey: "mock_version",
1896
+ property: "id",
1897
+ },
1898
+ },
1899
+ properties: {
1900
+ id: { type: "string" },
1901
+ name: { type: "string" },
1902
+ inherits_from_version_id: { type: ["string", "null"] },
1903
+ },
1904
+ required: ["id", "name"],
1905
+ additionalProperties: false,
1906
+ } as const satisfies LixSchemaDefinition;
1907
+
1908
+ // Store the schema
1909
+ await lix.db
1910
+ .insertInto("stored_schema")
1911
+ .values({ value: versionSchema })
1912
+ .execute();
1913
+
1914
+ const activeVersion = await lix.db
1915
+ .selectFrom("active_version")
1916
+ .select("version_id")
1917
+ .executeTakeFirstOrThrow();
1918
+
1919
+ // Insert parent and child versions
1920
+ await lix.db
1921
+ .insertInto("state_all")
1922
+ .values([
1923
+ {
1924
+ entity_id: "version0",
1925
+ file_id: "file1",
1926
+ schema_key: "mock_version",
1927
+ plugin_key: "test_plugin",
1928
+ version_id: activeVersion.version_id,
1929
+ snapshot_content: {
1930
+ id: "version0",
1931
+ name: "version0",
1932
+ inherits_from_version_id: null,
1933
+ },
1934
+ schema_version: "1.0",
1935
+ },
1936
+ {
1937
+ entity_id: "version1",
1938
+ file_id: "file1",
1939
+ schema_key: "mock_version",
1940
+ plugin_key: "test_plugin",
1941
+ version_id: activeVersion.version_id,
1942
+ snapshot_content: {
1943
+ id: "version1",
1944
+ name: "version1",
1945
+ inherits_from_version_id: "version0", // References version0
1946
+ },
1947
+ schema_version: "1.0",
1948
+ },
1949
+ ])
1950
+ .execute();
1951
+
1952
+ // This should fail - cannot delete version0 because version1 references it
1953
+ expect(() =>
1954
+ validateStateMutation({
1955
+ lix,
1956
+ schema: versionSchema,
1957
+ snapshot_content: {},
1958
+ operation: "delete",
1959
+ entity_id: "version0",
1960
+ version_id: activeVersion.version_id,
1961
+ })
1962
+ ).toThrowError(
1963
+ /Foreign key constraint violation.*referenced by.*mock_version.*inherits_from_version_id/
1964
+ );
1965
+
1966
+ // This should pass - can delete version1 (no other versions reference it)
1967
+ expect(() =>
1968
+ validateStateMutation({
1969
+ lix,
1970
+ schema: versionSchema,
1971
+ snapshot_content: {},
1972
+ operation: "delete",
1973
+ entity_id: "version1",
1974
+ version_id: activeVersion.version_id,
1975
+ })
1976
+ ).not.toThrowError();
1977
+ });
1978
+
1979
+ // Foreign keys are restricted to the current version context to maintain data integrity
1980
+ // and prevent confusing dependency relationships across version boundaries. While entities
1981
+ // can be inherited from parent versions through the copy-on-write system, foreign key
1982
+ // constraints require explicit, direct relationships within the same version scope.
1983
+ // This design choice ensures that:
1984
+ // 1. FK constraints are predictable and version-scoped
1985
+ // 2. No hidden dependencies exist across version boundaries
1986
+ // 3. Copy-on-write semantics remain clear and isolated
1987
+ // 4. Data integrity is maintained within each version context
1988
+ test("should prevent foreign key references to inherited entities from different version contexts", async () => {
1989
+ const lix = await openLix({});
1990
+
1991
+ // Create a thread in global context
1992
+ await lix.db
1993
+ .insertInto("thread_all")
1994
+ .values({
1995
+ id: "global_thread",
1996
+ metadata: { title: "Global Thread" },
1997
+ lixcol_version_id: "global",
1998
+ })
1999
+ .execute();
2000
+
2001
+ // Get the active version (should be "main" version)
2002
+ const activeVersion = await lix.db
2003
+ .selectFrom("active_version")
2004
+ .select("version_id")
2005
+ .executeTakeFirstOrThrow();
2006
+
2007
+ // Get the thread comment schema
2008
+ const threadCommentSchema = await lix.db
2009
+ .selectFrom("stored_schema")
2010
+ .select("value")
2011
+ .where("key", "=", "lix_thread_comment")
2012
+ .executeTakeFirstOrThrow();
2013
+
2014
+ // This should FAIL: attempting to create a thread_comment in the active version
2015
+ // that references a thread that only exists in global context.
2016
+ // Foreign keys should only work within the same version context.
2017
+ expect(() =>
2018
+ validateStateMutation({
2019
+ lix,
2020
+ schema: threadCommentSchema.value as LixSchemaDefinition,
2021
+ snapshot_content: {
2022
+ id: "comment1",
2023
+ thread_id: "global_thread", // References thread in global context
2024
+ parent_id: null,
2025
+ body: {
2026
+ type: "zettel_doc",
2027
+ content: [
2028
+ {
2029
+ type: "zettel_text_block",
2030
+ zettel_key: "test_key",
2031
+ style: "zettel_normal",
2032
+ children: [],
2033
+ },
2034
+ ],
2035
+ },
2036
+ },
2037
+ operation: "insert",
2038
+ version_id: activeVersion.version_id, // But creating comment in active version context
2039
+ })
2040
+ ).toThrow(/Foreign key constraint violation.*lix_thread.*global_thread/);
2041
+ });
2042
+
2043
+ test("should prevent change set elements from referencing change sets defined in global context", async () => {
2044
+ const lix = await openLix({});
2045
+
2046
+ // Create a change set in global context
2047
+ await lix.db
2048
+ .insertInto("change_set_all")
2049
+ .values({
2050
+ id: "global_change_set",
2051
+ lixcol_version_id: "global",
2052
+ })
2053
+ .execute();
2054
+
2055
+ // Get the active version (should be "main" version)
2056
+ const activeVersion = await lix.db
2057
+ .selectFrom("active_version")
2058
+ .select("version_id")
2059
+ .executeTakeFirstOrThrow();
2060
+
2061
+ // Get the change set element schema
2062
+ const changeSetElementSchema = await lix.db
2063
+ .selectFrom("stored_schema")
2064
+ .select("value")
2065
+ .where("key", "=", "lix_change_set_element")
2066
+ .executeTakeFirstOrThrow();
2067
+
2068
+ // This should FAIL: attempting to create a change_set_element in the active version
2069
+ // that references a change set that exists in global context.
2070
+ // The bug is that this currently passes when it should fail.
2071
+ expect(() =>
2072
+ validateStateMutation({
2073
+ lix,
2074
+ schema: changeSetElementSchema.value as LixSchemaDefinition,
2075
+ snapshot_content: {
2076
+ change_set_id: "global_change_set", // References change set in global context
2077
+ change_id: "dummy_change_id",
2078
+ entity_id: "dummy_entity_id",
2079
+ file_id: "dummy_file_id",
2080
+ schema_key: "dummy_schema_key",
2081
+ } satisfies ChangeSetElement,
2082
+ operation: "insert",
2083
+ version_id: activeVersion.version_id, // But creating element in active version context
2084
+ })
2085
+ ).toThrow(
2086
+ /Foreign key constraint violation.*lix_change_set.*global_change_set/
2087
+ );
2088
+ });
2089
+
2090
+ // Untracked state foreign key tests
2091
+ // SCENARIO: Tracked → Untracked Foreign Key Reference
2092
+ // WHY THIS TEST EXISTS: Untracked entities are local-only and won't be synced to remote.
2093
+ // If a tracked entity references an untracked entity, it would create broken references
2094
+ // when synced because the untracked entity doesn't exist on the remote.
2095
+ // BEHAVIOR: DISALLOWED - This would break data integrity during sync operations.
2096
+ test("should prevent tracked entities from referencing untracked entities", async () => {
2097
+ const lix = await openLix({});
2098
+
2099
+ const userSchema = {
2100
+ type: "object",
2101
+ "x-lix-version": "1.0",
2102
+ "x-lix-key": "user",
2103
+ "x-lix-primary-key": ["id"],
2104
+ properties: {
2105
+ id: { type: "string" },
2106
+ name: { type: "string" },
2107
+ },
2108
+ required: ["id", "name"],
2109
+ additionalProperties: false,
2110
+ } as const satisfies LixSchemaDefinition;
2111
+
2112
+ const postSchema = {
2113
+ type: "object",
2114
+ "x-lix-version": "1.0",
2115
+ "x-lix-key": "post",
2116
+ "x-lix-primary-key": ["id"],
2117
+ "x-lix-foreign-keys": {
2118
+ author_id: {
2119
+ schemaKey: "user",
2120
+ property: "id",
2121
+ },
2122
+ },
2123
+ properties: {
2124
+ id: { type: "string" },
2125
+ author_id: { type: "string" },
2126
+ title: { type: "string" },
2127
+ },
2128
+ required: ["id", "author_id", "title"],
2129
+ additionalProperties: false,
2130
+ } as const satisfies LixSchemaDefinition;
2131
+
2132
+ // Store schemas
2133
+ await lix.db
2134
+ .insertInto("stored_schema")
2135
+ .values([{ value: userSchema }, { value: postSchema }])
2136
+ .execute();
2137
+
2138
+ const activeVersion = await lix.db
2139
+ .selectFrom("active_version")
2140
+ .select("version_id")
2141
+ .executeTakeFirstOrThrow();
2142
+
2143
+ // Insert an untracked user
2144
+ await lix.db
2145
+ .insertInto("state_all")
2146
+ .values({
2147
+ entity_id: "untracked_user",
2148
+ file_id: "file1",
2149
+ schema_key: "user",
2150
+ plugin_key: "test_plugin",
2151
+ version_id: activeVersion.version_id,
2152
+ snapshot_content: {
2153
+ id: "untracked_user",
2154
+ name: "Untracked User",
2155
+ },
2156
+ schema_version: "1.0",
2157
+ untracked: true,
2158
+ })
2159
+ .execute();
2160
+
2161
+ // This should FAIL - tracked entity cannot reference untracked entity
2162
+ expect(() =>
2163
+ validateStateMutation({
2164
+ lix,
2165
+ schema: postSchema,
2166
+ snapshot_content: {
2167
+ id: "post1",
2168
+ author_id: "untracked_user", // References untracked user
2169
+ title: "My Post",
2170
+ },
2171
+ operation: "insert",
2172
+ version_id: activeVersion.version_id,
2173
+ })
2174
+ ).toThrow(
2175
+ /Foreign key constraint violation.*tracked entities cannot reference untracked entities.*This would create broken references during sync/
2176
+ );
2177
+ });
2178
+
2179
+ // SCENARIO: Untracked → Tracked Foreign Key Reference
2180
+ // WHY THIS TEST EXISTS: Untracked entities are local-only and won't be synced.
2181
+ // Since they remain local, they can safely reference tracked entities without
2182
+ // breaking data integrity. The untracked entity simply won't exist on remote.
2183
+ // BEHAVIOR: ALLOWED - Safe because untracked entities don't participate in sync.
2184
+ test("should allow untracked entities to reference tracked entities", async () => {
2185
+ const lix = await openLix({});
2186
+
2187
+ const userSchema = {
2188
+ type: "object",
2189
+ "x-lix-version": "1.0",
2190
+ "x-lix-key": "user",
2191
+ "x-lix-primary-key": ["id"],
2192
+ properties: {
2193
+ id: { type: "string" },
2194
+ name: { type: "string" },
2195
+ },
2196
+ required: ["id", "name"],
2197
+ additionalProperties: false,
2198
+ } as const satisfies LixSchemaDefinition;
2199
+
2200
+ const postSchema = {
2201
+ type: "object",
2202
+ "x-lix-version": "1.0",
2203
+ "x-lix-key": "post",
2204
+ "x-lix-primary-key": ["id"],
2205
+ "x-lix-foreign-keys": {
2206
+ author_id: {
2207
+ schemaKey: "user",
2208
+ property: "id",
2209
+ },
2210
+ },
2211
+ properties: {
2212
+ id: { type: "string" },
2213
+ author_id: { type: "string" },
2214
+ title: { type: "string" },
2215
+ },
2216
+ required: ["id", "author_id", "title"],
2217
+ additionalProperties: false,
2218
+ } as const satisfies LixSchemaDefinition;
2219
+
2220
+ // Store schemas
2221
+ await lix.db
2222
+ .insertInto("stored_schema")
2223
+ .values([{ value: userSchema }, { value: postSchema }])
2224
+ .execute();
2225
+
2226
+ const activeVersion = await lix.db
2227
+ .selectFrom("active_version")
2228
+ .select("version_id")
2229
+ .executeTakeFirstOrThrow();
2230
+
2231
+ // Insert a tracked user
2232
+ await lix.db
2233
+ .insertInto("state_all")
2234
+ .values({
2235
+ entity_id: "tracked_user",
2236
+ file_id: "file1",
2237
+ schema_key: "user",
2238
+ plugin_key: "test_plugin",
2239
+ version_id: activeVersion.version_id,
2240
+ snapshot_content: {
2241
+ id: "tracked_user",
2242
+ name: "Tracked User",
2243
+ },
2244
+ schema_version: "1.0",
2245
+ untracked: false,
2246
+ })
2247
+ .execute();
2248
+
2249
+ // Create validation arguments for untracked post
2250
+ const validationArgs = {
2251
+ lix,
2252
+ schema: postSchema,
2253
+ snapshot_content: {
2254
+ id: "untracked_post",
2255
+ author_id: "tracked_user", // References tracked user
2256
+ title: "My Untracked Post",
2257
+ },
2258
+ operation: "insert" as const,
2259
+ version_id: activeVersion.version_id,
2260
+ untracked: true, // Mark as untracked
2261
+ };
2262
+
2263
+ // This should PASS - untracked entity can reference tracked entity
2264
+ expect(() => validateStateMutation(validationArgs)).not.toThrow();
2265
+ });
2266
+
2267
+ // SCENARIO: Untracked → Untracked Foreign Key Reference
2268
+ // WHY THIS TEST EXISTS: Both entities are local-only and won't be synced.
2269
+ // They exist in the same local scope, so references between them are valid
2270
+ // and won't cause any sync issues since neither entity leaves the local system.
2271
+ // BEHAVIOR: ALLOWED - Both entities remain local, maintaining referential integrity.
2272
+ test("should allow untracked entities to reference other untracked entities", async () => {
2273
+ const lix = await openLix({});
2274
+
2275
+ const userSchema = {
2276
+ type: "object",
2277
+ "x-lix-version": "1.0",
2278
+ "x-lix-key": "user",
2279
+ "x-lix-primary-key": ["id"],
2280
+ properties: {
2281
+ id: { type: "string" },
2282
+ name: { type: "string" },
2283
+ },
2284
+ required: ["id", "name"],
2285
+ additionalProperties: false,
2286
+ } as const satisfies LixSchemaDefinition;
2287
+
2288
+ const postSchema = {
2289
+ type: "object",
2290
+ "x-lix-version": "1.0",
2291
+ "x-lix-key": "post",
2292
+ "x-lix-primary-key": ["id"],
2293
+ "x-lix-foreign-keys": {
2294
+ author_id: {
2295
+ schemaKey: "user",
2296
+ property: "id",
2297
+ },
2298
+ },
2299
+ properties: {
2300
+ id: { type: "string" },
2301
+ author_id: { type: "string" },
2302
+ title: { type: "string" },
2303
+ },
2304
+ required: ["id", "author_id", "title"],
2305
+ additionalProperties: false,
2306
+ } as const satisfies LixSchemaDefinition;
2307
+
2308
+ // Store schemas
2309
+ await lix.db
2310
+ .insertInto("stored_schema")
2311
+ .values([{ value: userSchema }, { value: postSchema }])
2312
+ .execute();
2313
+
2314
+ const activeVersion = await lix.db
2315
+ .selectFrom("active_version")
2316
+ .select("version_id")
2317
+ .executeTakeFirstOrThrow();
2318
+
2319
+ // Insert an untracked user
2320
+ await lix.db
2321
+ .insertInto("state_all")
2322
+ .values({
2323
+ entity_id: "untracked_user",
2324
+ file_id: "file1",
2325
+ schema_key: "user",
2326
+ plugin_key: "test_plugin",
2327
+ version_id: activeVersion.version_id,
2328
+ snapshot_content: {
2329
+ id: "untracked_user",
2330
+ name: "Untracked User",
2331
+ },
2332
+ schema_version: "1.0",
2333
+ untracked: true,
2334
+ })
2335
+ .execute();
2336
+
2337
+ // Create validation arguments for untracked post
2338
+ const validationArgs = {
2339
+ lix,
2340
+ schema: postSchema,
2341
+ snapshot_content: {
2342
+ id: "untracked_post",
2343
+ author_id: "untracked_user", // References untracked user
2344
+ title: "My Untracked Post",
2345
+ },
2346
+ operation: "insert" as const,
2347
+ version_id: activeVersion.version_id,
2348
+ untracked: true, // Mark as untracked
2349
+ };
2350
+
2351
+ // This should PASS - untracked entity can reference another untracked entity
2352
+ expect(() => validateStateMutation(validationArgs)).not.toThrow();
2353
+ });