@lix-js/sdk 0.4.7 → 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 -3
  365. package/dist/lix/index.d.ts.map +1 -1
  366. package/dist/lix/index.js +3 -6
  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 +1 -1
  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 -6
  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,2416 @@
1
+ import { test, expect, describe } from "vitest";
2
+ import { openLix } from "../lix/open-lix.js";
3
+ import type { LixSchemaDefinition } from "../schema-definition/definition.js";
4
+ import { Kysely, sql } from "kysely";
5
+ import { createVersion } from "../version/create-version.js";
6
+ import type { LixInternalDatabaseSchema } from "../database/schema.js";
7
+
8
+ test("select, insert, update, delete entity", async () => {
9
+ const mockSchema: LixSchemaDefinition = {
10
+ "x-lix-key": "mock_schema",
11
+ "x-lix-version": "1.0",
12
+ type: "object",
13
+ additionalProperties: false,
14
+ properties: {
15
+ value: {
16
+ type: "string",
17
+ },
18
+ },
19
+ };
20
+
21
+ const lix = await openLix({});
22
+
23
+ await lix.db
24
+ .insertInto("stored_schema")
25
+ .values({ value: mockSchema })
26
+ .execute();
27
+
28
+ await lix.db
29
+ .insertInto("state_all")
30
+ .values({
31
+ entity_id: "e0",
32
+ file_id: "f0",
33
+ schema_key: "mock_schema",
34
+ plugin_key: "lix_own_entity",
35
+ schema_version: "1.0",
36
+ version_id: sql`(SELECT version_id FROM active_version)`,
37
+ snapshot_content: {
38
+ value: "hello world",
39
+ },
40
+ })
41
+ .execute();
42
+
43
+ const viewAfterInsert = await lix.db
44
+ .selectFrom("state_all")
45
+ .where("schema_key", "=", "mock_schema")
46
+ .selectAll()
47
+ .execute();
48
+
49
+ expect(viewAfterInsert).toMatchObject([
50
+ {
51
+ entity_id: "e0",
52
+ file_id: "f0",
53
+ schema_key: "mock_schema",
54
+ plugin_key: "lix_own_entity",
55
+ snapshot_content: {
56
+ value: "hello world",
57
+ },
58
+ },
59
+ ]);
60
+
61
+ await lix.db
62
+ .updateTable("state_all")
63
+ .set({
64
+ snapshot_content: {
65
+ value: "hello world - updated",
66
+ },
67
+ })
68
+ .where("entity_id", "=", "e0")
69
+ .where("schema_key", "=", "mock_schema")
70
+ .where("file_id", "=", "f0")
71
+ .execute();
72
+
73
+ const viewAfterUpdate = await lix.db
74
+ .selectFrom("state_all")
75
+ .where("schema_key", "=", "mock_schema")
76
+ .selectAll()
77
+ .execute();
78
+
79
+ expect(viewAfterUpdate).toMatchObject([
80
+ {
81
+ entity_id: "e0",
82
+ file_id: "f0",
83
+ schema_key: "mock_schema",
84
+ plugin_key: "lix_own_entity",
85
+ snapshot_content: {
86
+ value: "hello world - updated",
87
+ },
88
+ },
89
+ ]);
90
+
91
+ await lix.db
92
+ .deleteFrom("state_all")
93
+ .where("entity_id", "=", "e0")
94
+ .where(
95
+ "version_id",
96
+ "=",
97
+ lix.db.selectFrom("active_version").select("version_id")
98
+ )
99
+ .where("schema_key", "=", "mock_schema")
100
+ .execute();
101
+
102
+ const viewAfterDelete = await lix.db
103
+ .selectFrom("state_all")
104
+ .where("schema_key", "=", "mock_schema")
105
+ .selectAll()
106
+ .execute();
107
+
108
+ expect(viewAfterDelete).toHaveLength(0);
109
+ });
110
+
111
+ test("validates the schema on insert", async () => {
112
+ const lix = await openLix({});
113
+
114
+ const mockSchema: LixSchemaDefinition = {
115
+ "x-lix-key": "mock_schema",
116
+ "x-lix-version": "1.0",
117
+ type: "object",
118
+ additionalProperties: false,
119
+ properties: {
120
+ value: {
121
+ type: "number",
122
+ },
123
+ },
124
+ };
125
+
126
+ await lix.db
127
+ .insertInto("stored_schema")
128
+ .values({ value: mockSchema })
129
+ .execute();
130
+ await expect(
131
+ lix.db
132
+ .insertInto("state_all")
133
+ .values({
134
+ entity_id: "e0",
135
+ file_id: "f0",
136
+ schema_key: "mock_schema",
137
+ plugin_key: "lix_own_entity",
138
+ schema_version: "1.0",
139
+ snapshot_content: {
140
+ value: "hello world",
141
+ },
142
+ version_id: sql`(SELECT version_id FROM active_version)`,
143
+ })
144
+ .execute()
145
+ ).rejects.toThrow(/value must be number/);
146
+ });
147
+
148
+ test("validates the schema on update", async () => {
149
+ const lix = await openLix({});
150
+
151
+ const mockSchema: LixSchemaDefinition = {
152
+ "x-lix-key": "mock_schema",
153
+ "x-lix-version": "1.0",
154
+ type: "object",
155
+ additionalProperties: false,
156
+ properties: {
157
+ value: {
158
+ type: "number",
159
+ },
160
+ },
161
+ };
162
+
163
+ await lix.db
164
+ .insertInto("stored_schema")
165
+ .values({ value: mockSchema })
166
+ .execute();
167
+
168
+ await lix.db
169
+ .insertInto("state_all")
170
+ .values({
171
+ entity_id: "e0",
172
+ file_id: "f0",
173
+ schema_key: "mock_schema",
174
+ plugin_key: "lix_own_entity",
175
+ schema_version: "1.0",
176
+ snapshot_content: {
177
+ value: 5,
178
+ },
179
+ version_id: sql`(SELECT version_id FROM active_version)`,
180
+ })
181
+ .execute();
182
+
183
+ await expect(
184
+ lix.db
185
+ .updateTable("state_all")
186
+ .set({
187
+ snapshot_content: {
188
+ value: "hello world - updated",
189
+ },
190
+ })
191
+ .where("entity_id", "=", "e0")
192
+ .where("schema_key", "=", "mock_schema")
193
+ .where("file_id", "=", "f0")
194
+ .execute()
195
+ ).rejects.toThrow(/value must be number/);
196
+
197
+ const viewAfterFailedUpdate = await lix.db
198
+ .selectFrom("state_all")
199
+ .where("schema_key", "=", "mock_schema")
200
+ .selectAll()
201
+ .execute();
202
+
203
+ expect(viewAfterFailedUpdate).toMatchObject([
204
+ {
205
+ entity_id: "e0",
206
+ file_id: "f0",
207
+ schema_key: "mock_schema",
208
+ plugin_key: "lix_own_entity",
209
+ snapshot_content: {
210
+ value: 5,
211
+ },
212
+ },
213
+ ]);
214
+ });
215
+
216
+ test("state is separated by version", async () => {
217
+ const lix = await openLix({});
218
+
219
+ await createVersion({ lix, id: "version_a" });
220
+ await createVersion({ lix, id: "version_b" });
221
+
222
+ await lix.db
223
+ .insertInto("state_all")
224
+ .values([
225
+ {
226
+ entity_id: "e0",
227
+ file_id: "f0",
228
+ schema_key: "mock_schema",
229
+ plugin_key: "mock_plugin",
230
+ schema_version: "1.0",
231
+ snapshot_content: {
232
+ value: "hello world from version a",
233
+ },
234
+ version_id: "version_a",
235
+ },
236
+ {
237
+ entity_id: "e0",
238
+ file_id: "f0",
239
+ schema_key: "mock_schema",
240
+ plugin_key: "mock_plugin",
241
+ schema_version: "1.0",
242
+ snapshot_content: {
243
+ value: "hello world from version b",
244
+ },
245
+ version_id: "version_b",
246
+ },
247
+ ])
248
+ .execute();
249
+
250
+ const stateAfterInserts = await lix.db
251
+ .selectFrom("state_all")
252
+ .where("schema_key", "=", "mock_schema")
253
+ .where("entity_id", "=", "e0")
254
+ .selectAll()
255
+ .execute();
256
+
257
+ expect(stateAfterInserts).toMatchObject([
258
+ {
259
+ entity_id: "e0",
260
+ file_id: "f0",
261
+ schema_key: "mock_schema",
262
+ plugin_key: "mock_plugin",
263
+ snapshot_content: {
264
+ value: "hello world from version a",
265
+ },
266
+ version_id: "version_a",
267
+ },
268
+ {
269
+ entity_id: "e0",
270
+ file_id: "f0",
271
+ schema_key: "mock_schema",
272
+ plugin_key: "mock_plugin",
273
+ snapshot_content: {
274
+ value: "hello world from version b",
275
+ },
276
+ version_id: "version_b",
277
+ },
278
+ ]);
279
+
280
+ // Verify timestamps are present
281
+ expect(stateAfterInserts[0]?.created_at).toBeDefined();
282
+ expect(stateAfterInserts[0]?.updated_at).toBeDefined();
283
+ expect(stateAfterInserts[1]?.created_at).toBeDefined();
284
+ expect(stateAfterInserts[1]?.updated_at).toBeDefined();
285
+
286
+ await lix.db
287
+ .updateTable("state_all")
288
+ .set({ snapshot_content: { value: "hello world from version b UPDATED" } })
289
+ .where("entity_id", "=", "e0")
290
+ .where("schema_key", "=", "mock_schema")
291
+ .where("version_id", "=", "version_b")
292
+ .execute();
293
+
294
+ const stateAfterUpdate = await lix.db
295
+ .selectFrom("state_all")
296
+ .where("schema_key", "=", "mock_schema")
297
+ .where("entity_id", "=", "e0")
298
+ .selectAll()
299
+ .execute();
300
+
301
+ expect(stateAfterUpdate).toMatchObject([
302
+ {
303
+ entity_id: "e0",
304
+ file_id: "f0",
305
+ schema_key: "mock_schema",
306
+ plugin_key: "mock_plugin",
307
+ snapshot_content: {
308
+ value: "hello world from version a",
309
+ },
310
+ version_id: "version_a",
311
+ },
312
+ {
313
+ entity_id: "e0",
314
+ file_id: "f0",
315
+ schema_key: "mock_schema",
316
+ plugin_key: "mock_plugin",
317
+ snapshot_content: {
318
+ value: "hello world from version b UPDATED",
319
+ },
320
+ version_id: "version_b",
321
+ },
322
+ ]);
323
+
324
+ await lix.db
325
+ .deleteFrom("state_all")
326
+ .where("entity_id", "=", "e0")
327
+ .where("version_id", "=", "version_b")
328
+ .execute();
329
+
330
+ const stateAfterDelete = await lix.db
331
+ .selectFrom("state_all")
332
+ .where("schema_key", "=", "mock_schema")
333
+ .where("entity_id", "=", "e0")
334
+ .selectAll()
335
+ .execute();
336
+
337
+ expect(stateAfterDelete).toMatchObject([
338
+ {
339
+ entity_id: "e0",
340
+ file_id: "f0",
341
+ schema_key: "mock_schema",
342
+ plugin_key: "mock_plugin",
343
+ snapshot_content: {
344
+ value: "hello world from version a",
345
+ },
346
+ version_id: "version_a",
347
+ },
348
+ ]);
349
+ });
350
+
351
+ test("created_at and updated_at timestamps are computed correctly", async () => {
352
+ const lix = await openLix({});
353
+
354
+ const mockSchema: LixSchemaDefinition = {
355
+ "x-lix-key": "mock_schema",
356
+ "x-lix-version": "1.0",
357
+ type: "object",
358
+ additionalProperties: false,
359
+ properties: {
360
+ value: {
361
+ type: "string",
362
+ },
363
+ },
364
+ };
365
+
366
+ await lix.db
367
+ .insertInto("stored_schema")
368
+ .values({ value: mockSchema })
369
+ .execute();
370
+
371
+ // Insert initial entity
372
+ await lix.db
373
+ .insertInto("state_all")
374
+ .values({
375
+ entity_id: "e0",
376
+ file_id: "f0",
377
+ schema_key: "mock_schema",
378
+ plugin_key: "lix_own_entity",
379
+ schema_version: "1.0",
380
+ version_id: sql`(SELECT version_id FROM active_version)`,
381
+ snapshot_content: {
382
+ value: "initial value",
383
+ },
384
+ })
385
+ .execute();
386
+
387
+ const stateAfterInsert = await lix.db
388
+ .selectFrom("state_all")
389
+ .where("entity_id", "=", "e0")
390
+ .selectAll()
391
+ .execute();
392
+
393
+ expect(stateAfterInsert).toHaveLength(1);
394
+ expect(stateAfterInsert[0]?.created_at).toBeDefined();
395
+ expect(stateAfterInsert[0]?.updated_at).toBeDefined();
396
+ expect(stateAfterInsert[0]?.created_at).toBe(stateAfterInsert[0]?.updated_at);
397
+
398
+ // Wait a bit to ensure different timestamps
399
+ await new Promise((resolve) => setTimeout(resolve, 1));
400
+
401
+ // Update the entity
402
+ await lix.db
403
+ .updateTable("state_all")
404
+ .set({
405
+ snapshot_content: {
406
+ value: "updated value",
407
+ },
408
+ })
409
+ .where("entity_id", "=", "e0")
410
+ .where("schema_key", "=", "mock_schema")
411
+ .execute();
412
+
413
+ const stateAfterUpdate = await lix.db
414
+ .selectFrom("state_all")
415
+ .where("entity_id", "=", "e0")
416
+ .selectAll()
417
+ .execute();
418
+
419
+ expect(stateAfterUpdate).toHaveLength(1);
420
+ expect(stateAfterUpdate[0]?.created_at).toBeDefined();
421
+ expect(stateAfterUpdate[0]?.updated_at).toBeDefined();
422
+ // created_at should remain the same
423
+ expect(stateAfterUpdate[0]?.created_at).toBe(stateAfterInsert[0]?.created_at);
424
+ // updated_at should be different (newer)
425
+ expect(stateAfterUpdate[0]?.updated_at).not.toBe(
426
+ stateAfterInsert[0]?.updated_at
427
+ );
428
+ expect(new Date(stateAfterUpdate[0]!.updated_at).getTime()).toBeGreaterThan(
429
+ new Date(stateAfterInsert[0]!.updated_at).getTime()
430
+ );
431
+ });
432
+
433
+ test("created_at and updated_at are version specific", async () => {
434
+ const lix = await openLix({});
435
+
436
+ await createVersion({ lix, id: "version_a" });
437
+ await createVersion({ lix, id: "version_b" });
438
+
439
+ const mockSchema: LixSchemaDefinition = {
440
+ "x-lix-key": "mock_schema",
441
+ "x-lix-version": "1.0",
442
+ additionalProperties: false,
443
+ type: "object",
444
+ properties: {
445
+ value: {
446
+ type: "string",
447
+ },
448
+ },
449
+ };
450
+
451
+ await lix.db
452
+ .insertInto("stored_schema")
453
+ .values({ value: mockSchema })
454
+ .execute();
455
+
456
+ // Insert entity in version A
457
+ await lix.db
458
+ .insertInto("state_all")
459
+ .values({
460
+ entity_id: "e0",
461
+ file_id: "f0",
462
+ schema_key: "mock_schema",
463
+ plugin_key: "lix_own_entity",
464
+ schema_version: "1.0",
465
+ version_id: "version_a",
466
+ snapshot_content: {
467
+ value: "value in version a",
468
+ },
469
+ })
470
+ .execute();
471
+
472
+ // Wait a bit to ensure different timestamps
473
+ await new Promise((resolve) => setTimeout(resolve, 1));
474
+
475
+ // Insert same entity in version B
476
+ await lix.db
477
+ .insertInto("state_all")
478
+ .values({
479
+ entity_id: "e0",
480
+ file_id: "f0",
481
+ schema_key: "mock_schema",
482
+ plugin_key: "lix_own_entity",
483
+ schema_version: "1.0",
484
+ version_id: "version_b",
485
+ snapshot_content: {
486
+ value: "value in version b",
487
+ },
488
+ })
489
+ .execute();
490
+
491
+ const stateVersionA = await lix.db
492
+ .selectFrom("state_all")
493
+ .where("entity_id", "=", "e0")
494
+ .where("version_id", "=", "version_a")
495
+ .selectAll()
496
+ .execute();
497
+
498
+ const stateVersionB = await lix.db
499
+ .selectFrom("state_all")
500
+ .where("entity_id", "=", "e0")
501
+ .where("version_id", "=", "version_b")
502
+ .selectAll()
503
+ .execute();
504
+
505
+ expect(stateVersionA).toHaveLength(1);
506
+ expect(stateVersionB).toHaveLength(1);
507
+
508
+ // Both should have timestamps
509
+ expect(stateVersionA[0]?.created_at).toBeDefined();
510
+ expect(stateVersionA[0]?.updated_at).toBeDefined();
511
+ expect(stateVersionB[0]?.created_at).toBeDefined();
512
+ expect(stateVersionB[0]?.updated_at).toBeDefined();
513
+
514
+ // the same entity has been inserted but with different changes
515
+ expect(stateVersionA[0]?.created_at).not.toBe(stateVersionB[0]?.created_at);
516
+
517
+ // Wait and update only version B
518
+ await new Promise((resolve) => setTimeout(resolve, 1));
519
+
520
+ await lix.db
521
+ .updateTable("state_all")
522
+ .set({
523
+ snapshot_content: {
524
+ value: "updated value in version b",
525
+ },
526
+ })
527
+ .where("entity_id", "=", "e0")
528
+ .where("version_id", "=", "version_b")
529
+ .execute();
530
+
531
+ const updatedStateVersionA = await lix.db
532
+ .selectFrom("state_all")
533
+ .where("entity_id", "=", "e0")
534
+ .where("version_id", "=", "version_a")
535
+ .selectAll()
536
+ .execute();
537
+
538
+ const updatedStateVersionB = await lix.db
539
+ .selectFrom("state_all")
540
+ .where("entity_id", "=", "e0")
541
+ .where("version_id", "=", "version_b")
542
+ .selectAll()
543
+ .execute();
544
+
545
+ // Version A should remain unchanged
546
+ expect(updatedStateVersionA[0]?.updated_at).toBe(
547
+ stateVersionA[0]?.updated_at
548
+ );
549
+
550
+ // Version B should have updated timestamp
551
+ expect(updatedStateVersionB[0]?.updated_at).not.toBe(
552
+ stateVersionB[0]?.updated_at
553
+ );
554
+ expect(
555
+ new Date(updatedStateVersionB[0]!.updated_at).getTime()
556
+ ).toBeGreaterThan(new Date(stateVersionB[0]!.updated_at).getTime());
557
+ });
558
+
559
+ test("state appears in both versions when they share the same change set", async () => {
560
+ const lix = await openLix({});
561
+
562
+ const versionA = await createVersion({ lix, id: "version_a" });
563
+ // Insert state into version A
564
+ await lix.db
565
+ .insertInto("state_all")
566
+ .values({
567
+ entity_id: "e0",
568
+ file_id: "f0",
569
+ schema_key: "mock_schema",
570
+ plugin_key: "mock_plugin",
571
+ schema_version: "1.0",
572
+ snapshot_content: {
573
+ value: "shared state",
574
+ },
575
+ version_id: "version_a",
576
+ })
577
+ .execute();
578
+
579
+ const versionAAfterInsert = await lix.db
580
+ .selectFrom("version")
581
+ .where("id", "=", versionA.id)
582
+ .selectAll()
583
+ .executeTakeFirstOrThrow();
584
+
585
+ // Create version B with the same change set as version A
586
+ await createVersion({
587
+ lix,
588
+ id: "version_b",
589
+ changeSet: { id: versionAAfterInsert.change_set_id },
590
+ });
591
+
592
+ const stateInBothVersions = await lix.db
593
+ .selectFrom("state_all")
594
+ .where("schema_key", "=", "mock_schema")
595
+ .where("entity_id", "=", "e0")
596
+ .selectAll()
597
+ .execute();
598
+
599
+ // Both versions should see the same state
600
+ expect(stateInBothVersions).toMatchObject([
601
+ {
602
+ entity_id: "e0",
603
+ schema_key: "mock_schema",
604
+ snapshot_content: { value: "shared state" },
605
+ version_id: "version_a",
606
+ },
607
+ {
608
+ entity_id: "e0",
609
+ schema_key: "mock_schema",
610
+ snapshot_content: { value: "shared state" },
611
+ version_id: "version_b",
612
+ },
613
+ ]);
614
+ });
615
+
616
+ test("state diverges when versions have common ancestor but different changes", async () => {
617
+ const lix = await openLix({});
618
+
619
+ // Create base version and add initial state
620
+ const baseVersion = await createVersion({ lix, id: "base_version" });
621
+
622
+ await lix.db
623
+ .insertInto("state_all")
624
+ .values({
625
+ entity_id: "e0",
626
+ file_id: "f0",
627
+ schema_key: "mock_schema",
628
+ plugin_key: "mock_plugin",
629
+ schema_version: "1.0",
630
+ snapshot_content: {
631
+ value: "base state",
632
+ },
633
+ version_id: "base_version",
634
+ })
635
+ .execute();
636
+
637
+ const baseVersionAfterInsert = await lix.db
638
+ .selectFrom("version")
639
+ .where("id", "=", baseVersion.id)
640
+ .selectAll()
641
+ .executeTakeFirstOrThrow();
642
+
643
+ // Create two versions from the same base changeset
644
+ await createVersion({
645
+ lix,
646
+ id: "version_a",
647
+ changeSet: { id: baseVersionAfterInsert.change_set_id },
648
+ });
649
+
650
+ await createVersion({
651
+ lix,
652
+ id: "version_b",
653
+ changeSet: { id: baseVersionAfterInsert.change_set_id },
654
+ });
655
+
656
+ const versions = await lix.db
657
+ .selectFrom("version")
658
+ .where("id", "in", ["base_version", "version_a", "version_b"])
659
+ .select(["id", "change_set_id"])
660
+ .execute();
661
+
662
+ expect(versions).toHaveLength(3);
663
+
664
+ // Both versions should initially see the base state
665
+ const initialState = await lix.db
666
+ .selectFrom("state_all")
667
+ .where("schema_key", "=", "mock_schema")
668
+ .where("entity_id", "=", "e0")
669
+ .selectAll()
670
+ .execute();
671
+
672
+ expect(initialState).toHaveLength(3); // base, version_a, version_b
673
+
674
+ // Update state in version A
675
+ await lix.db
676
+ .updateTable("state_all")
677
+ .set({
678
+ snapshot_content: { value: "updated in version A" },
679
+ })
680
+ .where("entity_id", "=", "e0")
681
+ .where("version_id", "=", "version_a")
682
+ .execute();
683
+
684
+ // Update state in version B differently
685
+ await lix.db
686
+ .updateTable("state_all")
687
+ .set({
688
+ snapshot_content: { value: "updated in version B" },
689
+ })
690
+ .where("entity_id", "=", "e0")
691
+ .where("version_id", "=", "version_b")
692
+ .execute();
693
+
694
+ const divergedState = await lix.db
695
+ .selectFrom("state_all")
696
+ .where("schema_key", "=", "mock_schema")
697
+ .where("entity_id", "=", "e0")
698
+ .selectAll()
699
+ .execute();
700
+
701
+ // All three versions should have different states
702
+ expect(divergedState).toMatchObject([
703
+ {
704
+ entity_id: "e0",
705
+ snapshot_content: { value: "base state" },
706
+ version_id: "base_version",
707
+ },
708
+ {
709
+ entity_id: "e0",
710
+ snapshot_content: { value: "updated in version A" },
711
+ version_id: "version_a",
712
+ },
713
+ {
714
+ entity_id: "e0",
715
+ snapshot_content: { value: "updated in version B" },
716
+ version_id: "version_b",
717
+ },
718
+ ]);
719
+ });
720
+
721
+ // Write-through cache behavior tests
722
+ test("write-through cache: insert operations populate cache immediately", async () => {
723
+ const lix = await openLix({});
724
+
725
+ const activeVersion = await lix.db
726
+ .selectFrom("active_version")
727
+ .innerJoin("version", "active_version.version_id", "version.id")
728
+ .selectAll("version")
729
+ .executeTakeFirstOrThrow();
730
+
731
+ // Insert state data - should populate cache via write-through
732
+ await lix.db
733
+ .insertInto("state_all")
734
+ .values({
735
+ entity_id: "write-through-entity",
736
+ schema_key: "write-through-schema",
737
+ file_id: "write-through-file",
738
+ plugin_key: "write-through-plugin",
739
+ snapshot_content: { test: "write-through-data" },
740
+ schema_version: "1.0",
741
+ version_id: activeVersion.id,
742
+ })
743
+ .execute();
744
+
745
+ // Cache should be populated immediately via write-through
746
+ const cacheEntry = await (
747
+ lix.db as unknown as Kysely<LixInternalDatabaseSchema>
748
+ )
749
+ .selectFrom("internal_state_cache")
750
+ .where("entity_id", "=", "write-through-entity")
751
+ .where("schema_key", "=", "write-through-schema")
752
+ .where("file_id", "=", "write-through-file")
753
+ .where("version_id", "=", activeVersion.id)
754
+ .selectAll()
755
+ .executeTakeFirst();
756
+
757
+ expect(cacheEntry).toBeDefined();
758
+ expect(cacheEntry?.entity_id).toBe("write-through-entity");
759
+ expect(cacheEntry?.plugin_key).toBe("write-through-plugin");
760
+ expect(cacheEntry?.snapshot_content).toEqual({
761
+ test: "write-through-data",
762
+ });
763
+
764
+ // State view should return the same data (from cache)
765
+ const stateResults = await lix.db
766
+ .selectFrom("state_all")
767
+ .where("entity_id", "=", "write-through-entity")
768
+ .selectAll()
769
+ .execute();
770
+
771
+ expect(stateResults).toHaveLength(1);
772
+ expect(stateResults[0]?.entity_id).toBe("write-through-entity");
773
+ expect(stateResults[0]?.snapshot_content).toEqual({
774
+ test: "write-through-data",
775
+ });
776
+ });
777
+
778
+ test("write-through cache: update operations update cache immediately", async () => {
779
+ const lix = await openLix({});
780
+
781
+ const activeVersion = await lix.db
782
+ .selectFrom("active_version")
783
+ .innerJoin("version", "active_version.version_id", "version.id")
784
+ .selectAll("version")
785
+ .executeTakeFirstOrThrow();
786
+
787
+ // Insert initial state
788
+ await lix.db
789
+ .insertInto("state_all")
790
+ .values({
791
+ entity_id: "update-cache-entity",
792
+ schema_key: "update-cache-schema",
793
+ file_id: "update-cache-file",
794
+ plugin_key: "initial-plugin",
795
+ snapshot_content: { initial: "value" },
796
+ schema_version: "1.0",
797
+ version_id: activeVersion.id,
798
+ })
799
+ .execute();
800
+
801
+ // Update the state - should update cache via write-through
802
+ await lix.db
803
+ .updateTable("state_all")
804
+ .set({
805
+ snapshot_content: { updated: "value" },
806
+ plugin_key: "updated-plugin",
807
+ })
808
+ .where("entity_id", "=", "update-cache-entity")
809
+ .where("schema_key", "=", "update-cache-schema")
810
+ .where("file_id", "=", "update-cache-file")
811
+ .where("version_id", "=", activeVersion.id)
812
+ .execute();
813
+
814
+ // Cache should be immediately updated
815
+ const cacheEntry = await (
816
+ lix.db as unknown as Kysely<LixInternalDatabaseSchema>
817
+ )
818
+ .selectFrom("internal_state_cache")
819
+ .where("entity_id", "=", "update-cache-entity")
820
+ .where("schema_key", "=", "update-cache-schema")
821
+ .where("file_id", "=", "update-cache-file")
822
+ .where("version_id", "=", activeVersion.id)
823
+ .selectAll()
824
+ .executeTakeFirst();
825
+
826
+ expect(cacheEntry).toBeDefined();
827
+ expect(cacheEntry?.snapshot_content).toEqual({
828
+ updated: "value",
829
+ });
830
+ expect(cacheEntry?.plugin_key).toBe("updated-plugin");
831
+
832
+ // State view should return updated data
833
+ const stateResults = await lix.db
834
+ .selectFrom("state_all")
835
+ .where("entity_id", "=", "update-cache-entity")
836
+ .selectAll()
837
+ .execute();
838
+
839
+ expect(stateResults).toHaveLength(1);
840
+ expect(stateResults[0]?.snapshot_content).toEqual({ updated: "value" });
841
+ expect(stateResults[0]?.plugin_key).toBe("updated-plugin");
842
+ });
843
+
844
+ test("delete operations remove entries from underlying data", async () => {
845
+ const lix = await openLix({});
846
+
847
+ const activeVersion = await lix.db
848
+ .selectFrom("active_version")
849
+ .innerJoin("version", "active_version.version_id", "version.id")
850
+ .selectAll("version")
851
+ .executeTakeFirstOrThrow();
852
+
853
+ // Insert initial state
854
+ await lix.db
855
+ .insertInto("state_all")
856
+ .values({
857
+ entity_id: "delete-cache-entity",
858
+ schema_key: "delete-cache-schema",
859
+ file_id: "delete-cache-file",
860
+ plugin_key: "delete-plugin",
861
+ snapshot_content: { to: "delete" },
862
+ schema_version: "1.0",
863
+ version_id: activeVersion.id,
864
+ })
865
+ .execute();
866
+
867
+ // Verify data exists
868
+ const beforeDelete = await lix.db
869
+ .selectFrom("state_all")
870
+ .where("entity_id", "=", "delete-cache-entity")
871
+ .selectAll()
872
+ .execute();
873
+
874
+ expect(beforeDelete).toHaveLength(1);
875
+
876
+ // Delete the state - this creates a deletion change (doesn't physically remove cache entry)
877
+ await lix.db
878
+ .deleteFrom("state_all")
879
+ .where("entity_id", "=", "delete-cache-entity")
880
+ .where("schema_key", "=", "delete-cache-schema")
881
+ .where("file_id", "=", "delete-cache-file")
882
+ .where("version_id", "=", activeVersion.id)
883
+ .execute();
884
+
885
+ // Data should no longer be accessible through state view
886
+ const afterDelete = await lix.db
887
+ .selectFrom("state_all")
888
+ .where("entity_id", "=", "delete-cache-entity")
889
+ .selectAll()
890
+ .execute();
891
+
892
+ expect(afterDelete).toHaveLength(0);
893
+ });
894
+
895
+ test("change.created_at and state timestamps are consistent", async () => {
896
+ const lix = await openLix({});
897
+
898
+ const mockSchema: LixSchemaDefinition = {
899
+ "x-lix-key": "mock_schema",
900
+ "x-lix-version": "1.0",
901
+ type: "object",
902
+ additionalProperties: false,
903
+ properties: {
904
+ value: {
905
+ type: "string",
906
+ },
907
+ },
908
+ };
909
+
910
+ await lix.db
911
+ .insertInto("stored_schema")
912
+ .values({ value: mockSchema })
913
+ .execute();
914
+
915
+ // Insert state data
916
+ await lix.db
917
+ .insertInto("state_all")
918
+ .values({
919
+ entity_id: "timestamp-test-entity",
920
+ schema_key: "mock_schema",
921
+ file_id: "timestamp-test-file",
922
+ plugin_key: "timestamp-test-plugin",
923
+ snapshot_content: { value: "timestamp test" },
924
+ schema_version: "1.0",
925
+ version_id: sql`(SELECT version_id FROM active_version)`,
926
+ })
927
+ .execute();
928
+
929
+ // Get the change record
930
+ const changeRecord = await (
931
+ lix.db as unknown as Kysely<LixInternalDatabaseSchema>
932
+ )
933
+ .selectFrom("internal_change")
934
+ .where("entity_id", "=", "timestamp-test-entity")
935
+ .where("schema_key", "=", "mock_schema")
936
+ .select(["created_at"])
937
+ .executeTakeFirstOrThrow();
938
+
939
+ // Get the state cache record
940
+ const cacheRecord = await (
941
+ lix.db as unknown as Kysely<LixInternalDatabaseSchema>
942
+ )
943
+ .selectFrom("internal_state_cache")
944
+ .where("entity_id", "=", "timestamp-test-entity")
945
+ .where("schema_key", "=", "mock_schema")
946
+ .select(["created_at", "updated_at"])
947
+ .executeTakeFirstOrThrow();
948
+
949
+ // Verify all timestamps are identical
950
+ expect(changeRecord.created_at).toBe(cacheRecord.created_at);
951
+ expect(changeRecord.created_at).toBe(cacheRecord.updated_at);
952
+ });
953
+
954
+ test("state and state_all views expose change_id for blame and diff functionality", async () => {
955
+ const lix = await openLix({});
956
+
957
+ const mockSchema: LixSchemaDefinition = {
958
+ "x-lix-key": "mock_schema",
959
+ "x-lix-version": "1.0",
960
+ type: "object",
961
+ additionalProperties: false,
962
+ properties: {
963
+ value: {
964
+ type: "string",
965
+ },
966
+ },
967
+ };
968
+
969
+ await lix.db
970
+ .insertInto("stored_schema")
971
+ .values({ value: mockSchema })
972
+ .execute();
973
+
974
+ // Insert initial state using Kysely to ensure virtual table is triggered
975
+ await lix.db
976
+ .insertInto("state_all")
977
+ .values({
978
+ entity_id: "change-id-test-entity",
979
+ schema_key: "mock_schema",
980
+ file_id: "change-id-test-file",
981
+ plugin_key: "change-id-test-plugin",
982
+ snapshot_content: { value: "initial value" },
983
+ schema_version: "1.0",
984
+ version_id: sql`(SELECT version_id FROM active_version)`,
985
+ })
986
+ .execute();
987
+
988
+ // Query state_all view to verify change_id is exposed
989
+ const stateAllResult = await lix.db
990
+ .selectFrom("state_all")
991
+ .where("entity_id", "=", "change-id-test-entity")
992
+ .where("schema_key", "=", "mock_schema")
993
+ .selectAll()
994
+ .execute();
995
+
996
+ expect(stateAllResult).toHaveLength(1);
997
+ expect(stateAllResult[0]?.change_id).toBeDefined();
998
+ expect(typeof stateAllResult[0]?.change_id).toBe("string");
999
+
1000
+ // Query state view (filtered by active version) to verify change_id is exposed
1001
+ const stateResult = await lix.db
1002
+ .selectFrom("state")
1003
+ .where("entity_id", "=", "change-id-test-entity")
1004
+ .where("schema_key", "=", "mock_schema")
1005
+ .selectAll()
1006
+ .execute();
1007
+
1008
+ expect(stateResult).toHaveLength(1);
1009
+ expect(stateResult[0]?.change_id).toBeDefined();
1010
+ expect(typeof stateResult[0]?.change_id).toBe("string");
1011
+
1012
+ // Verify that change_id matches between state and state_all views
1013
+ expect(stateResult[0]?.change_id).toBe(stateAllResult[0]?.change_id);
1014
+
1015
+ // Get the actual change record to verify the change_id is correct
1016
+ const changeRecord = await lix.db
1017
+ .selectFrom("change")
1018
+ .where("entity_id", "=", "change-id-test-entity")
1019
+ .where("schema_key", "=", "mock_schema")
1020
+ .select(["change.id", "snapshot_content"])
1021
+ .executeTakeFirstOrThrow();
1022
+
1023
+ // Verify that the change_id in the views matches the actual change.id
1024
+ expect(stateResult[0]?.change_id).toBe(changeRecord.id);
1025
+ expect(stateAllResult[0]?.change_id).toBe(changeRecord.id);
1026
+
1027
+ // Verify that the snapshot content in the change matches the state view
1028
+ expect(changeRecord.snapshot_content).toEqual({ value: "initial value" });
1029
+ expect(stateResult[0]?.snapshot_content).toEqual({ value: "initial value" });
1030
+
1031
+ // Update the entity to create a new change
1032
+ await lix.db
1033
+ .updateTable("state_all")
1034
+ .set({
1035
+ snapshot_content: { value: "updated value" },
1036
+ })
1037
+ .where("entity_id", "=", "change-id-test-entity")
1038
+ .where("schema_key", "=", "mock_schema")
1039
+ .execute();
1040
+
1041
+ // Query again to verify change_id updated after modification
1042
+ const updatedStateResult = await lix.db
1043
+ .selectFrom("state_all")
1044
+ .where("entity_id", "=", "change-id-test-entity")
1045
+ .where("schema_key", "=", "mock_schema")
1046
+ .selectAll()
1047
+ .execute();
1048
+
1049
+ expect(updatedStateResult).toHaveLength(1);
1050
+ expect(updatedStateResult[0]?.change_id).toBeDefined();
1051
+ // The change_id should be different after the update (new change created)
1052
+ expect(updatedStateResult[0]?.change_id).not.toBe(stateResult[0]?.change_id);
1053
+
1054
+ // Get the new change record
1055
+ const newChangeRecord = await lix.db
1056
+ .selectFrom("change")
1057
+ .where("entity_id", "=", "change-id-test-entity")
1058
+ .where("schema_key", "=", "mock_schema")
1059
+ .orderBy("created_at", "desc")
1060
+ .select(["change.id", "snapshot_content"])
1061
+ .executeTakeFirstOrThrow();
1062
+
1063
+ // Verify the new change_id matches the latest change
1064
+ expect(updatedStateResult[0]?.change_id).toBe(newChangeRecord.id);
1065
+
1066
+ // Verify that the updated snapshot content in the change matches the state view
1067
+ expect(newChangeRecord.snapshot_content).toEqual({ value: "updated value" });
1068
+ expect(updatedStateResult[0]?.snapshot_content).toEqual({
1069
+ value: "updated value",
1070
+ });
1071
+ });
1072
+
1073
+ // Important to note that only a full cache clear (like during schema changes) triggers
1074
+ // a cache miss and repopulation from the CTE at the moment!
1075
+ //
1076
+ // This is simpler, at the cost of state inconsistencies when changes are made
1077
+ // without populating or invalidating the cache.
1078
+ test.todo(
1079
+ "state view should work and re-populate the cache after cache is fully (!) cleared",
1080
+ async () => {
1081
+ const lix = await openLix({});
1082
+
1083
+ // Insert a key-value pair
1084
+ await lix.db
1085
+ .insertInto("key_value")
1086
+ .values({
1087
+ key: "test_cache_miss",
1088
+ value: "initial_value",
1089
+ })
1090
+ .execute();
1091
+
1092
+ // Verify it's accessible through state view (should populate cache)
1093
+ const stateBeforeCacheClear = await lix.db
1094
+ .selectFrom("state_all")
1095
+ .where("schema_key", "=", "lix_key_value")
1096
+ .where("entity_id", "=", "test_cache_miss")
1097
+ .selectAll()
1098
+ .execute();
1099
+
1100
+ expect(stateBeforeCacheClear).toHaveLength(1);
1101
+ expect(stateBeforeCacheClear[0]).toMatchObject({
1102
+ entity_id: "test_cache_miss",
1103
+ schema_key: "lix_key_value",
1104
+ snapshot_content: {
1105
+ key: "test_cache_miss",
1106
+ value: "initial_value",
1107
+ },
1108
+ });
1109
+
1110
+ // Verify it's in the cache
1111
+ const cacheBeforeClear = await (
1112
+ lix.db as unknown as Kysely<LixInternalDatabaseSchema>
1113
+ )
1114
+ .selectFrom("internal_state_cache")
1115
+ .where("schema_key", "=", "lix_key_value")
1116
+ .where("entity_id", "=", "test_cache_miss")
1117
+ .selectAll()
1118
+ .execute();
1119
+
1120
+ expect(cacheBeforeClear).toHaveLength(1);
1121
+
1122
+ // Simulate cache invalidation (like what happens during stored_schema insertion)
1123
+ await (lix.db as unknown as Kysely<LixInternalDatabaseSchema>)
1124
+ .deleteFrom("internal_state_cache")
1125
+ .execute();
1126
+
1127
+ // Verify cache is empty
1128
+ const cacheAfterClear = await (
1129
+ lix.db as unknown as Kysely<LixInternalDatabaseSchema>
1130
+ )
1131
+ .selectFrom("internal_state_cache")
1132
+ .selectAll()
1133
+ .execute();
1134
+
1135
+ expect(cacheAfterClear).toHaveLength(0);
1136
+
1137
+ // Try to access the same data through state view again
1138
+ // This should trigger cache miss logic and repopulate from CTE
1139
+ const stateAfterCacheClear = await lix.db
1140
+ .selectFrom("state_all")
1141
+ .where("schema_key", "=", "lix_key_value")
1142
+ .where("entity_id", "=", "test_cache_miss")
1143
+ .selectAll()
1144
+ .execute();
1145
+
1146
+ // This should work - if cache miss logic is working correctly
1147
+ expect(stateAfterCacheClear).toHaveLength(1);
1148
+ expect(stateAfterCacheClear[0]).toMatchObject({
1149
+ entity_id: "test_cache_miss",
1150
+ schema_key: "lix_key_value",
1151
+ snapshot_content: {
1152
+ key: "test_cache_miss",
1153
+ value: "initial_value",
1154
+ },
1155
+ });
1156
+
1157
+ // Verify cache was repopulated
1158
+ const cacheAfterRefill = await (
1159
+ lix.db as unknown as Kysely<LixInternalDatabaseSchema>
1160
+ )
1161
+ .selectFrom("internal_state_cache")
1162
+ .where("schema_key", "=", "lix_key_value")
1163
+ .where("entity_id", "=", "test_cache_miss")
1164
+ .selectAll()
1165
+ .execute();
1166
+
1167
+ expect(cacheAfterRefill).toHaveLength(1);
1168
+ }
1169
+ );
1170
+
1171
+ test("delete operations are validated for foreign key constraints", async () => {
1172
+ const lix = await openLix({});
1173
+
1174
+ // Define parent schema (referenced entity)
1175
+ const parentSchema: LixSchemaDefinition = {
1176
+ "x-lix-key": "parent_entity",
1177
+ "x-lix-version": "1.0",
1178
+ "x-lix-primary-key": ["id"],
1179
+ type: "object",
1180
+ properties: {
1181
+ id: { type: "string" },
1182
+ name: { type: "string" },
1183
+ },
1184
+ required: ["id", "name"],
1185
+ additionalProperties: false,
1186
+ };
1187
+
1188
+ // Define child schema with foreign key to parent
1189
+ const childSchema: LixSchemaDefinition = {
1190
+ "x-lix-key": "child_entity",
1191
+ "x-lix-version": "1.0",
1192
+ "x-lix-primary-key": ["id"],
1193
+ "x-lix-foreign-keys": {
1194
+ parent_id: {
1195
+ schemaKey: "parent_entity",
1196
+ property: "id",
1197
+ },
1198
+ },
1199
+ type: "object",
1200
+ properties: {
1201
+ id: { type: "string" },
1202
+ parent_id: { type: "string" },
1203
+ value: { type: "string" },
1204
+ },
1205
+ required: ["id", "parent_id", "value"],
1206
+ additionalProperties: false,
1207
+ };
1208
+
1209
+ // Register both schemas
1210
+ await lix.db
1211
+ .insertInto("stored_schema")
1212
+ .values([{ value: parentSchema }, { value: childSchema }])
1213
+ .execute();
1214
+
1215
+ // Insert parent entity
1216
+ await lix.db
1217
+ .insertInto("state_all")
1218
+ .values({
1219
+ entity_id: "parent-1",
1220
+ schema_key: "parent_entity",
1221
+ file_id: "test-file",
1222
+ plugin_key: "test-plugin",
1223
+ snapshot_content: {
1224
+ id: "parent-1",
1225
+ name: "Parent Entity",
1226
+ },
1227
+ schema_version: "1.0",
1228
+ version_id: sql`(SELECT version_id FROM active_version)`,
1229
+ })
1230
+ .execute();
1231
+
1232
+ // Insert child entity that references the parent
1233
+ await lix.db
1234
+ .insertInto("state_all")
1235
+ .values({
1236
+ entity_id: "child-1",
1237
+ schema_key: "child_entity",
1238
+ file_id: "test-file",
1239
+ plugin_key: "test-plugin",
1240
+ snapshot_content: {
1241
+ id: "child-1",
1242
+ parent_id: "parent-1",
1243
+ value: "Child Value",
1244
+ },
1245
+ schema_version: "1.0",
1246
+ version_id: sql`(SELECT version_id FROM active_version)`,
1247
+ })
1248
+ .execute();
1249
+
1250
+ // Verify both entities exist
1251
+ const parentBefore = await lix.db
1252
+ .selectFrom("state_all")
1253
+ .where("entity_id", "=", "parent-1")
1254
+ .where("schema_key", "=", "parent_entity")
1255
+ .selectAll()
1256
+ .execute();
1257
+
1258
+ const childBefore = await lix.db
1259
+ .selectFrom("state_all")
1260
+ .where("entity_id", "=", "child-1")
1261
+ .where("schema_key", "=", "child_entity")
1262
+ .selectAll()
1263
+ .execute();
1264
+
1265
+ expect(parentBefore).toHaveLength(1);
1266
+ expect(childBefore).toHaveLength(1);
1267
+
1268
+ // Attempting to delete the parent entity should fail due to foreign key constraint
1269
+ // because there's a child entity that references it
1270
+ await expect(
1271
+ lix.db
1272
+ .deleteFrom("state_all")
1273
+ .where("entity_id", "=", "parent-1")
1274
+ .where("schema_key", "=", "parent_entity")
1275
+ .execute()
1276
+ ).rejects.toThrow(/foreign key/i);
1277
+
1278
+ // Verify the parent still exists after failed deletion attempt
1279
+ const parentAfter = await lix.db
1280
+ .selectFrom("state_all")
1281
+ .where("entity_id", "=", "parent-1")
1282
+ .where("schema_key", "=", "parent_entity")
1283
+ .selectAll()
1284
+ .execute();
1285
+
1286
+ expect(parentAfter).toHaveLength(1);
1287
+ });
1288
+
1289
+ describe.each([
1290
+ { scenario: "cache hit", clearCache: false },
1291
+ // { scenario: "cache miss", clearCache: true },
1292
+ ])(
1293
+ "($scenario) inheritance should work - child version should see entities from parent version",
1294
+ ({ clearCache }) => {
1295
+ test("child version inherits entities from parent version", async () => {
1296
+ const lix = await openLix({});
1297
+
1298
+ // Insert an entity into global version
1299
+ await lix.db
1300
+ .insertInto("state_all")
1301
+ .values({
1302
+ entity_id: "global-entity-1",
1303
+ file_id: "test-file",
1304
+ schema_key: "test_schema",
1305
+ plugin_key: "test_plugin",
1306
+ version_id: "global",
1307
+ snapshot_content: {
1308
+ id: "global-entity-1",
1309
+ name: "Global Entity",
1310
+ },
1311
+ schema_version: "1.0",
1312
+ })
1313
+ .execute();
1314
+
1315
+ // Create a child version that inherits from global
1316
+ const childVersion = await createVersion({
1317
+ lix,
1318
+ name: "child-version",
1319
+ });
1320
+
1321
+ // Verify inheritance was set up correctly
1322
+ expect(childVersion.inherits_from_version_id).toBe("global");
1323
+
1324
+ if (clearCache) {
1325
+ // Clear the state cache to force re-materialization with inheritance (CTE path)
1326
+ lix.sqlite.exec("DELETE FROM internal_state_cache");
1327
+ }
1328
+ // If clearCache is false, we test the cache hit path
1329
+
1330
+ // The child version should inherit the entity from global
1331
+ const inheritedEntity = await lix.db
1332
+ .selectFrom("state_all")
1333
+ .where("entity_id", "=", "global-entity-1")
1334
+ .where("version_id", "=", childVersion.id)
1335
+ .selectAll()
1336
+ .execute();
1337
+
1338
+ // This should pass - the entity should be visible in the child version via inheritance
1339
+ expect(inheritedEntity).toHaveLength(1);
1340
+ expect(inheritedEntity[0]?.entity_id).toBe("global-entity-1");
1341
+ expect(inheritedEntity[0]?.version_id).toBe(childVersion.id); // Should return child version ID
1342
+ expect(inheritedEntity[0]?.inherited_from_version_id).toBe("global"); // Should track inheritance source
1343
+ expect(inheritedEntity[0]?.snapshot_content).toEqual({
1344
+ id: "global-entity-1",
1345
+ name: "Global Entity",
1346
+ });
1347
+ });
1348
+
1349
+ // Flaky cache CTE
1350
+ test.todo(
1351
+ "inherited entities should reflect changes in parent",
1352
+ async () => {
1353
+ const lix = await openLix({});
1354
+
1355
+ // Get the main version
1356
+ const mainVersion = await lix.db
1357
+ .selectFrom("version")
1358
+ .where("name", "=", "main")
1359
+ .selectAll()
1360
+ .executeTakeFirstOrThrow();
1361
+
1362
+ const originalChangeSetId = mainVersion.change_set_id;
1363
+
1364
+ // Make a mutation to trigger version update in global context
1365
+ await lix.db
1366
+ .insertInto("key_value_all")
1367
+ .values({
1368
+ key: "cache_rebuild_test_key",
1369
+ value: "cache_rebuild_test_value",
1370
+ lixcol_version_id: mainVersion.id,
1371
+ })
1372
+ .execute();
1373
+
1374
+ // Check the global version after mutation
1375
+ const globalVersionAfterMutation = await lix.db
1376
+ .selectFrom("state_all")
1377
+ .where("schema_key", "=", "lix_version")
1378
+ .where("entity_id", "=", mainVersion.id)
1379
+ .where("version_id", "=", "global")
1380
+ .selectAll()
1381
+ .executeTakeFirst();
1382
+
1383
+ console.log("🌍 Global version after mutation:", {
1384
+ change_set_id: (globalVersionAfterMutation?.snapshot_content as any)
1385
+ ?.change_set_id,
1386
+ original: originalChangeSetId,
1387
+ });
1388
+
1389
+ if (clearCache) {
1390
+ // Clear the cache to force a rebuild from CTE
1391
+ await (lix.db as unknown as Kysely<LixInternalDatabaseSchema>)
1392
+ .deleteFrom("internal_state_cache")
1393
+ .execute();
1394
+ }
1395
+
1396
+ const state = await lix.db
1397
+ .selectFrom("state_all")
1398
+ .where("schema_key", "=", "lix_version")
1399
+ .where("entity_id", "=", mainVersion.id)
1400
+ .selectAll()
1401
+ .execute();
1402
+
1403
+ console.log(
1404
+ "🔍 State query result:",
1405
+ state.map((s) => ({
1406
+ entity_id: s.entity_id,
1407
+ version_id: s.version_id,
1408
+ change_set_id: (s.snapshot_content as any).change_set_id,
1409
+ inherited_from_version_id: s.inherited_from_version_id,
1410
+ }))
1411
+ );
1412
+
1413
+ // testing for cached contents first to make a cache miss test fail faster
1414
+ const cacheContents = await (
1415
+ lix.db as unknown as Kysely<LixInternalDatabaseSchema>
1416
+ )
1417
+ .selectFrom("internal_state_cache")
1418
+ .where("schema_key", "=", "lix_version")
1419
+ .where("entity_id", "=", mainVersion.id)
1420
+ .selectAll()
1421
+ .execute();
1422
+
1423
+ // Both version entries should have the same updated change_set_id
1424
+ const cachedInheritedMainVersion = cacheContents.find(
1425
+ (entry) => entry.version_id === mainVersion.id
1426
+ );
1427
+ const cachedMainVersionGlobal = cacheContents.find(
1428
+ (entry) => entry.version_id === "global"
1429
+ );
1430
+
1431
+ // we have copy on write deletion in place, so the cache should not contain the inherited version
1432
+ expect(cachedInheritedMainVersion).toBeUndefined();
1433
+ expect(cachedMainVersionGlobal).toBeDefined();
1434
+
1435
+ // Both version entries should have the same updated change_set_id
1436
+ const inheritedMainVersion = state.find(
1437
+ (entry) => entry.version_id === mainVersion.id
1438
+ );
1439
+ const mainVersionGlobal = state.find(
1440
+ (entry) => entry.version_id === "global"
1441
+ );
1442
+
1443
+ expect(inheritedMainVersion).toBeDefined();
1444
+ expect(mainVersionGlobal).toBeDefined();
1445
+
1446
+ // Both should have the same change_set_id
1447
+ expect(
1448
+ (inheritedMainVersion?.snapshot_content as any).change_set_id
1449
+ ).toEqual((mainVersionGlobal?.snapshot_content as any).change_set_id);
1450
+
1451
+ // The change_set_id should be different from the original change_set_Id
1452
+ expect(
1453
+ (inheritedMainVersion?.snapshot_content as any).change_set_id
1454
+ ).not.toEqual(originalChangeSetId);
1455
+ expect(
1456
+ (mainVersionGlobal?.snapshot_content as any).change_set_id
1457
+ ).not.toEqual(originalChangeSetId);
1458
+
1459
+ expect(
1460
+ (cachedMainVersionGlobal?.snapshot_content as any).change_set_id
1461
+ ).toEqual(mainVersionGlobal?.snapshot_content.change_set_id);
1462
+ }
1463
+ );
1464
+ }
1465
+ );
1466
+
1467
+ // TODO flaky test https://github.com/opral/lix-sdk/issues/308
1468
+ describe.skip.each([
1469
+ { scenario: "cache hit", clearCache: false },
1470
+ { scenario: "cache miss", clearCache: true },
1471
+ ])(
1472
+ "($scenario) updating an inherited entity in child version should create a copy-on-write entity",
1473
+ () => {
1474
+ test("child version inherits then overrides with own entity", async () => {
1475
+ const lix = await openLix({});
1476
+
1477
+ // Insert an entity into global version
1478
+ await lix.db
1479
+ .insertInto("state_all")
1480
+ .values({
1481
+ entity_id: "shared-entity",
1482
+ file_id: "test-file",
1483
+ schema_key: "test_schema",
1484
+ plugin_key: "test_plugin",
1485
+ version_id: "global",
1486
+ snapshot_content: {
1487
+ id: "shared-entity",
1488
+ name: "Original Global Value",
1489
+ count: 1,
1490
+ },
1491
+ schema_version: "1.0",
1492
+ })
1493
+ .execute();
1494
+
1495
+ // Create a child version that inherits from global
1496
+ const childVersion = await createVersion({
1497
+ lix,
1498
+ name: "child-version",
1499
+ });
1500
+
1501
+ // Note: For cache miss testing, we'll clear cache AFTER the update operation
1502
+
1503
+ // Verify the child initially sees the inherited entity
1504
+ const inheritedEntity = await lix.db
1505
+ .selectFrom("state_all")
1506
+ .where("entity_id", "=", "shared-entity")
1507
+ .where("version_id", "=", childVersion.id)
1508
+ .selectAll()
1509
+ .execute();
1510
+
1511
+ expect(inheritedEntity).toHaveLength(1);
1512
+ expect(inheritedEntity[0]?.version_id).toBe(childVersion.id);
1513
+ expect(inheritedEntity[0]?.inherited_from_version_id).toBe("global");
1514
+ expect(inheritedEntity[0]?.snapshot_content).toEqual({
1515
+ id: "shared-entity",
1516
+ name: "Original Global Value",
1517
+ count: 1,
1518
+ });
1519
+
1520
+ // Now modify the entity in the child version (copy-on-write)
1521
+ await lix.db
1522
+ .updateTable("state_all")
1523
+ .set({
1524
+ snapshot_content: {
1525
+ id: "shared-entity",
1526
+ name: "Modified in Child Version",
1527
+ count: 2,
1528
+ },
1529
+ })
1530
+ .where("entity_id", "=", "shared-entity")
1531
+ .where("version_id", "=", childVersion.id)
1532
+ .execute();
1533
+
1534
+ // Clear cache after update to test cache miss scenario
1535
+ // if (clearCache) {
1536
+ // lix.sqlite.exec("DELETE FROM internal_state_cache");
1537
+ // }
1538
+
1539
+ // Verify the child now has its own version of the entity
1540
+ const childEntity = await lix.db
1541
+ .selectFrom("state_all")
1542
+ .where("entity_id", "=", "shared-entity")
1543
+ .where("version_id", "=", childVersion.id)
1544
+ .selectAll()
1545
+ .execute();
1546
+
1547
+ expect(childEntity).toHaveLength(1);
1548
+ expect(childEntity[0]?.version_id).toBe(childVersion.id);
1549
+ expect(childEntity[0]?.inherited_from_version_id).toBe(null); // No longer inherited
1550
+ expect(childEntity[0]?.snapshot_content).toEqual({
1551
+ id: "shared-entity",
1552
+ name: "Modified in Child Version",
1553
+ count: 2,
1554
+ });
1555
+
1556
+ // Verify the global version still has the original value
1557
+ const globalEntity = await lix.db
1558
+ .selectFrom("state_all")
1559
+ .where("entity_id", "=", "shared-entity")
1560
+ .where("version_id", "=", "global")
1561
+ .selectAll()
1562
+ .execute();
1563
+
1564
+ expect(globalEntity).toHaveLength(1);
1565
+ expect(globalEntity[0]?.version_id).toBe("global");
1566
+ expect(globalEntity[0]?.inherited_from_version_id).toBe(null);
1567
+ expect(globalEntity[0]?.snapshot_content).toEqual({
1568
+ id: "shared-entity",
1569
+ name: "Original Global Value",
1570
+ count: 1,
1571
+ });
1572
+
1573
+ // Verify we now have 2 separate entities (one in global, one in child)
1574
+ const allEntities = await lix.db
1575
+ .selectFrom("state_all")
1576
+ .where("entity_id", "=", "shared-entity")
1577
+ .selectAll()
1578
+ .execute();
1579
+
1580
+ expect(allEntities).toHaveLength(2);
1581
+
1582
+ // Sort by version_id for consistent ordering
1583
+ allEntities.sort((a, b) => a.version_id.localeCompare(b.version_id));
1584
+
1585
+ // Child version entity (modified)
1586
+ expect(allEntities[0]?.version_id).toBe(childVersion.id);
1587
+ expect(allEntities[0]?.inherited_from_version_id).toBe(null);
1588
+ expect(allEntities[0]?.snapshot_content).toEqual({
1589
+ id: "shared-entity",
1590
+ name: "Modified in Child Version",
1591
+ count: 2,
1592
+ });
1593
+
1594
+ // Global version entity (original)
1595
+ expect(allEntities[1]?.version_id).toBe("global");
1596
+ expect(allEntities[1]?.inherited_from_version_id).toBe(null);
1597
+ expect(allEntities[1]?.snapshot_content).toEqual({
1598
+ id: "shared-entity",
1599
+ name: "Original Global Value",
1600
+ count: 1,
1601
+ });
1602
+ });
1603
+ }
1604
+ );
1605
+
1606
+ describe.each([
1607
+ { scenario: "cache hit", clearCache: false },
1608
+ { scenario: "cache miss", clearCache: true },
1609
+ ])(
1610
+ "($scenario) deleting an inherited entity should create copy-on-write deletion",
1611
+ ({ clearCache }) => {
1612
+ test.todo(
1613
+ "child version deletes inherited entity via copy-on-write",
1614
+ async () => {
1615
+ const mockSchema: LixSchemaDefinition = {
1616
+ "x-lix-key": "test_schema",
1617
+ "x-lix-version": "1.0",
1618
+ type: "object",
1619
+ additionalProperties: false,
1620
+ properties: {
1621
+ id: { type: "string" },
1622
+ name: { type: "string" },
1623
+ },
1624
+ };
1625
+
1626
+ const lix = await openLix({});
1627
+
1628
+ const activeVersion = await lix.db
1629
+ .selectFrom("active_version")
1630
+ .innerJoin("version", "active_version.version_id", "version.id")
1631
+ .selectAll("version")
1632
+ .executeTakeFirstOrThrow();
1633
+
1634
+ // Insert schema
1635
+ await lix.db
1636
+ .insertInto("stored_schema")
1637
+ .values({ value: mockSchema })
1638
+ .execute();
1639
+
1640
+ // Insert an entity into global version
1641
+ await lix.db
1642
+ .insertInto("state_all")
1643
+ .values({
1644
+ entity_id: "shared-entity",
1645
+ file_id: "test-file",
1646
+ schema_key: "test_schema",
1647
+ plugin_key: "test_plugin",
1648
+ version_id: "global",
1649
+ snapshot_content: {
1650
+ id: "shared-entity",
1651
+ name: "shared Entity",
1652
+ },
1653
+ schema_version: "1.0",
1654
+ })
1655
+ .execute();
1656
+
1657
+ if (clearCache) {
1658
+ // Clear the state cache to force re-materialization with inheritance (CTE path)
1659
+ lix.sqlite.exec("DELETE FROM internal_state_cache");
1660
+ }
1661
+ // If clearCache is false, we test the cache hit path
1662
+
1663
+ // Verify the child initially sees the inherited entity
1664
+ const inheritedEntity = await lix.db
1665
+ .selectFrom("state_all")
1666
+ .where("entity_id", "=", "shared-entity")
1667
+ .where("version_id", "=", activeVersion.id)
1668
+ .selectAll()
1669
+ .execute();
1670
+
1671
+ expect(inheritedEntity).toHaveLength(1);
1672
+ expect(inheritedEntity[0]?.version_id).toBe(activeVersion.id);
1673
+ expect(inheritedEntity[0]?.inherited_from_version_id).toBe("global");
1674
+
1675
+ // Delete the inherited entity in child version (should create copy-on-write deletion)
1676
+ await lix.db
1677
+ .deleteFrom("state_all")
1678
+ .where("entity_id", "=", "shared-entity")
1679
+ .where("version_id", "=", activeVersion.id)
1680
+ .execute();
1681
+
1682
+ if (clearCache) {
1683
+ // Clear cache after deletion to test CTE path for subsequent queries
1684
+ lix.sqlite.exec("DELETE FROM internal_state_cache");
1685
+ }
1686
+
1687
+ // Verify the entity is deleted in child version
1688
+ const childEntityAfterDelete = await lix.db
1689
+ .selectFrom("state_all")
1690
+ .where("entity_id", "=", "shared-entity")
1691
+ .where("version_id", "=", activeVersion.id)
1692
+ .selectAll()
1693
+ .execute();
1694
+
1695
+ // Entity should be deleted in child version (copy-on-write deletion)
1696
+ expect(childEntityAfterDelete).toHaveLength(0);
1697
+
1698
+ // Verify the entity still exists in global version (not affected by child deletion)
1699
+ const inheritedEntityAfterDelete = await lix.db
1700
+ .selectFrom("state_all")
1701
+ .where("entity_id", "=", "shared-entity")
1702
+ .where("version_id", "=", "global")
1703
+ .selectAll()
1704
+ .execute();
1705
+
1706
+ expect(inheritedEntityAfterDelete).toHaveLength(1);
1707
+ expect(inheritedEntityAfterDelete[0]?.snapshot_content).toEqual({
1708
+ id: "shared-entity",
1709
+ name: "shared Entity",
1710
+ });
1711
+
1712
+ // Verify we now only see the global entity through the state view (deletion marker is hidden)
1713
+ const allEntities = await lix.db
1714
+ .selectFrom("state_all")
1715
+ .where("entity_id", "=", "shared-entity")
1716
+ .selectAll()
1717
+ .execute();
1718
+
1719
+ // Debug: Log what entities we actually got in cache miss scenario
1720
+ if (clearCache && allEntities.length !== 1) {
1721
+ console.log(
1722
+ `Cache miss scenario returned ${allEntities.length} entities:`,
1723
+ allEntities.map((e) => ({
1724
+ version_id: e.version_id,
1725
+ inherited_from_version_id: e.inherited_from_version_id,
1726
+ snapshot_content: e.snapshot_content,
1727
+ }))
1728
+ );
1729
+ }
1730
+
1731
+ // Both cache hit and cache miss scenarios should behave identically:
1732
+ // copy-on-write deletion hides the entity from child but preserves it in parent
1733
+ expect(allEntities).toHaveLength(1);
1734
+ expect(allEntities[0]?.version_id).toBe("global");
1735
+ expect(allEntities[0]?.inherited_from_version_id).toBe(null); // It's the original global entity
1736
+ }
1737
+ );
1738
+ }
1739
+ );
1740
+
1741
+ // TODO flaky test (ordering of deletions)
1742
+ test.todo(
1743
+ "deleting without filtering for the version_id deletes the entity from all versions",
1744
+ async () => {
1745
+ const lix = await openLix({});
1746
+
1747
+ // Insert an entity into global version
1748
+ await lix.db
1749
+ .insertInto("state_all")
1750
+ .values({
1751
+ entity_id: "shared-entity",
1752
+ file_id: "test-file",
1753
+ schema_key: "test_schema",
1754
+ plugin_key: "test_plugin",
1755
+ version_id: "global",
1756
+ snapshot_content: {
1757
+ id: "shared-entity",
1758
+ name: "Global Entity",
1759
+ },
1760
+ schema_version: "1.0",
1761
+ })
1762
+ .execute();
1763
+
1764
+ // Create a child version that inherits from global
1765
+ const childVersion = await createVersion({
1766
+ lix,
1767
+ name: "child-version",
1768
+ inherits_from_version_id: "global",
1769
+ });
1770
+
1771
+ // Verify inheritance - both global and child should see the entity
1772
+ const beforeDelete = await lix.db
1773
+ .selectFrom("state_all")
1774
+ .where("entity_id", "=", "shared-entity")
1775
+ .where("version_id", "in", ["global", childVersion.id])
1776
+ .selectAll()
1777
+ .execute();
1778
+
1779
+ expect(beforeDelete).toHaveLength(2); // One in global, one inherited in child
1780
+ expect(beforeDelete).toMatchObject([
1781
+ {
1782
+ entity_id: "shared-entity",
1783
+ version_id: "global",
1784
+ inherited_from_version_id: null,
1785
+ snapshot_content: { id: "shared-entity", name: "Global Entity" },
1786
+ },
1787
+ {
1788
+ entity_id: "shared-entity",
1789
+ version_id: childVersion.id,
1790
+ inherited_from_version_id: "global",
1791
+ snapshot_content: { id: "shared-entity", name: "Global Entity" },
1792
+ },
1793
+ ]);
1794
+
1795
+ await lix.db
1796
+ .deleteFrom("state_all")
1797
+ .where("entity_id", "=", "shared-entity")
1798
+ .where("schema_key", "=", "test_schema")
1799
+ .execute();
1800
+
1801
+ const afterDelete = await lix.db
1802
+ .selectFrom("state_all")
1803
+ .where("entity_id", "=", "shared-entity")
1804
+ .selectAll()
1805
+ .execute();
1806
+
1807
+ // Should be deleted from every version
1808
+ expect(afterDelete).toHaveLength(0);
1809
+ }
1810
+ );
1811
+
1812
+ // todo @martin-lysk the insert or ignore is not working as expected
1813
+ // i am not fixing this now to avoid merge conflicts in the xUpdate function
1814
+ test.todo(
1815
+ "INSERT OR IGNORE into state virtual table should not throw validation errors for duplicates or update the row",
1816
+ async () => {
1817
+ const lix = await openLix({});
1818
+
1819
+ // First, insert a record successfully
1820
+ await lix.db
1821
+ .insertInto("state_all")
1822
+ .values({
1823
+ entity_id: "test-duplicate-entity",
1824
+ schema_key: "test_schema",
1825
+ file_id: "test",
1826
+ plugin_key: "test_plugin",
1827
+ snapshot_content: { id: "test-duplicate-entity", name: "Original" },
1828
+ schema_version: "1.0",
1829
+ version_id: "global",
1830
+ })
1831
+ .execute();
1832
+
1833
+ // Verify the record exists
1834
+ const originalRecord = await lix.db
1835
+ .selectFrom("state_all")
1836
+ .where("entity_id", "=", "test-duplicate-entity")
1837
+ .selectAll()
1838
+ .executeTakeFirst();
1839
+
1840
+ expect(originalRecord).toBeDefined();
1841
+ expect(originalRecord?.snapshot_content).toMatchObject({
1842
+ id: "test-duplicate-entity",
1843
+ name: "Original",
1844
+ });
1845
+
1846
+ // Now try to INSERT OR IGNORE the same entity - this should NOT throw an error
1847
+ // but currently it does because validation runs before OR IGNORE logic
1848
+ expect(() => {
1849
+ lix.sqlite.exec(`
1850
+ INSERT OR IGNORE INTO state (
1851
+ entity_id, schema_key, file_id, plugin_key,
1852
+ snapshot_content, schema_version, version_id
1853
+ ) VALUES (
1854
+ 'test-duplicate-entity', 'test_schema', 'test', 'test_plugin',
1855
+ '{"id":"test-duplicate-entity","name":"Duplicate"}', '1.0', 'global'
1856
+ )
1857
+ `);
1858
+ }).not.toThrow(); // This should not throw, but currently does
1859
+
1860
+ // Verify the original record is unchanged (OR IGNORE should have ignored the duplicate)
1861
+ const afterIgnore = await lix.db
1862
+ .selectFrom("state_all")
1863
+ .where("entity_id", "=", "test-duplicate-entity")
1864
+ .selectAll()
1865
+ .executeTakeFirst();
1866
+
1867
+ expect(afterIgnore?.snapshot_content).toMatchObject({
1868
+ id: "test-duplicate-entity",
1869
+ name: "Original", // Should still be original, not "Duplicate"
1870
+ });
1871
+ }
1872
+ );
1873
+
1874
+ test("should emit state_commit hook when database transaction commits", async () => {
1875
+ const lix = await openLix({});
1876
+
1877
+ const mockSchema: LixSchemaDefinition = {
1878
+ "x-lix-key": "mock_schema",
1879
+ "x-lix-version": "1.0",
1880
+ type: "object",
1881
+ additionalProperties: false,
1882
+ properties: {
1883
+ value: {
1884
+ type: "string",
1885
+ },
1886
+ },
1887
+ };
1888
+
1889
+ await lix.db
1890
+ .insertInto("stored_schema")
1891
+ .values({ value: mockSchema })
1892
+ .execute();
1893
+
1894
+ // Set up hook listener
1895
+ let hookCallCount = 0;
1896
+ lix.hooks.onStateCommit(() => {
1897
+ hookCallCount++;
1898
+ });
1899
+
1900
+ // Perform a database operation that should trigger the hook
1901
+ await lix.db
1902
+ .insertInto("state_all")
1903
+ .values({
1904
+ entity_id: "test-entity",
1905
+ file_id: "test-file",
1906
+ schema_key: "mock_schema",
1907
+ plugin_key: "test_plugin",
1908
+ schema_version: "1.0",
1909
+ version_id: sql`(SELECT version_id FROM active_version)`,
1910
+ snapshot_content: {
1911
+ value: "test value",
1912
+ },
1913
+ })
1914
+ .execute();
1915
+
1916
+ // Hook should have been called once
1917
+ expect(hookCallCount).toBe(1);
1918
+
1919
+ // Perform another operation
1920
+ await lix.db
1921
+ .updateTable("state_all")
1922
+ .set({
1923
+ snapshot_content: {
1924
+ value: "updated value",
1925
+ },
1926
+ })
1927
+ .where("entity_id", "=", "test-entity")
1928
+ .execute();
1929
+
1930
+ // Hook should have been called twice now
1931
+ expect(hookCallCount).toBe(2);
1932
+ });
1933
+
1934
+ test("untracked mutations don't trigger change control", async () => {
1935
+ const lix = await openLix({});
1936
+
1937
+ const mockSchema: LixSchemaDefinition = {
1938
+ "x-lix-key": "mock_schema",
1939
+ "x-lix-version": "1.0",
1940
+ type: "object",
1941
+ additionalProperties: false,
1942
+ properties: {
1943
+ value: {
1944
+ type: "string",
1945
+ },
1946
+ },
1947
+ };
1948
+
1949
+ await lix.db
1950
+ .insertInto("stored_schema")
1951
+ .values({ value: mockSchema })
1952
+ .execute();
1953
+
1954
+ // Count changes before any untracked mutations
1955
+ const changesInitial = await lix.db
1956
+ .selectFrom("change")
1957
+ .selectAll()
1958
+ .execute();
1959
+
1960
+ // 1. INSERT untracked state
1961
+ await lix.db
1962
+ .insertInto("state_all")
1963
+ .values({
1964
+ entity_id: "untracked-entity",
1965
+ file_id: "test-file",
1966
+ schema_key: "mock_schema",
1967
+ plugin_key: "test_plugin",
1968
+ schema_version: "1.0",
1969
+ version_id: sql`(SELECT version_id FROM active_version)`,
1970
+ snapshot_content: {
1971
+ value: "untracked value",
1972
+ },
1973
+ untracked: true,
1974
+ })
1975
+ .execute();
1976
+
1977
+ // Count changes after untracked insert
1978
+ const changesAfterInsert = await lix.db
1979
+ .selectFrom("change")
1980
+ .selectAll()
1981
+ .execute();
1982
+
1983
+ // Number of changes should be identical (no change control for untracked)
1984
+ expect(changesAfterInsert.length).toBe(changesInitial.length);
1985
+
1986
+ // Verify the untracked entity exists in state view
1987
+ const untrackedState = await lix.db
1988
+ .selectFrom("state_all")
1989
+ .where("entity_id", "=", "untracked-entity")
1990
+ .selectAll()
1991
+ .execute();
1992
+
1993
+ expect(untrackedState).toHaveLength(1);
1994
+ expect(untrackedState[0]?.snapshot_content).toEqual({
1995
+ value: "untracked value",
1996
+ });
1997
+ expect(untrackedState[0]?.untracked).toBe(1);
1998
+
1999
+ // 2. UPDATE untracked state
2000
+ await lix.db
2001
+ .updateTable("state_all")
2002
+ .where("entity_id", "=", "untracked-entity")
2003
+ .set({
2004
+ snapshot_content: {
2005
+ value: "untracked value updated",
2006
+ },
2007
+ untracked: true,
2008
+ })
2009
+ .execute();
2010
+
2011
+ // Count changes after untracked update
2012
+ const changesAfterUpdate = await lix.db
2013
+ .selectFrom("change")
2014
+ .selectAll()
2015
+ .execute();
2016
+
2017
+ // Number of changes should still be identical (no change control for untracked)
2018
+ expect(changesAfterUpdate.length).toBe(changesInitial.length);
2019
+
2020
+ // Verify the untracked entity was updated
2021
+ const updatedState = await lix.db
2022
+ .selectFrom("state_all")
2023
+ .where("entity_id", "=", "untracked-entity")
2024
+ .selectAll()
2025
+ .execute();
2026
+
2027
+ expect(updatedState).toHaveLength(1);
2028
+ expect(updatedState[0]?.snapshot_content).toEqual({
2029
+ value: "untracked value updated",
2030
+ });
2031
+ expect(updatedState[0]?.untracked).toBe(1);
2032
+
2033
+ // 3. DELETE untracked state
2034
+ await lix.db
2035
+ .deleteFrom("state_all")
2036
+ .where("entity_id", "=", "untracked-entity")
2037
+ .execute();
2038
+
2039
+ // Count changes after untracked delete
2040
+ const changesAfterDelete = await lix.db
2041
+ .selectFrom("change")
2042
+ .selectAll()
2043
+ .execute();
2044
+
2045
+ // Number of changes should still be identical (no change control for untracked)
2046
+ expect(changesAfterDelete.length).toBe(changesInitial.length);
2047
+
2048
+ // Verify the untracked entity was deleted
2049
+ const deletedState = await lix.db
2050
+ .selectFrom("state_all")
2051
+ .where("entity_id", "=", "untracked-entity")
2052
+ .selectAll()
2053
+ .execute();
2054
+
2055
+ expect(deletedState).toHaveLength(0);
2056
+ });
2057
+
2058
+ test("tracked update to previously untracked entity deletes untracked state", async () => {
2059
+ const lix = await openLix({});
2060
+
2061
+ const mockSchema: LixSchemaDefinition = {
2062
+ "x-lix-key": "mock_schema",
2063
+ "x-lix-version": "1.0",
2064
+ type: "object",
2065
+ additionalProperties: false,
2066
+ properties: {
2067
+ value: {
2068
+ type: "string",
2069
+ },
2070
+ },
2071
+ };
2072
+
2073
+ await lix.db
2074
+ .insertInto("stored_schema")
2075
+ .values({ value: mockSchema })
2076
+ .execute();
2077
+
2078
+ // Insert untracked state
2079
+ await lix.db
2080
+ .insertInto("state_all")
2081
+ .values({
2082
+ entity_id: "override-entity",
2083
+ file_id: "test-file",
2084
+ schema_key: "mock_schema",
2085
+ plugin_key: "test_plugin",
2086
+ schema_version: "1.0",
2087
+ version_id: sql`(SELECT version_id FROM active_version)`,
2088
+ snapshot_content: {
2089
+ value: "untracked value",
2090
+ },
2091
+ untracked: true,
2092
+ })
2093
+ .execute();
2094
+
2095
+ // Verify untracked state exists
2096
+ const untrackedState = await lix.db
2097
+ .selectFrom("state_all")
2098
+ .where("entity_id", "=", "override-entity")
2099
+ .selectAll()
2100
+ .execute();
2101
+
2102
+ expect(untrackedState).toHaveLength(1);
2103
+ expect(untrackedState[0]?.snapshot_content).toEqual({
2104
+ value: "untracked value",
2105
+ });
2106
+
2107
+ // Now update the untracked entity to make it tracked (should delete from untracked table)
2108
+ await lix.db
2109
+ .updateTable("state_all")
2110
+ .set({
2111
+ snapshot_content: {
2112
+ value: "tracked value",
2113
+ },
2114
+ untracked: false,
2115
+ })
2116
+ .where("entity_id", "=", "override-entity")
2117
+ .where("schema_key", "=", "mock_schema")
2118
+ .execute();
2119
+
2120
+ // Verify tracked state has overridden untracked state
2121
+ const finalState = await lix.db
2122
+ .selectFrom("state_all")
2123
+ .where("entity_id", "=", "override-entity")
2124
+ .selectAll()
2125
+ .execute();
2126
+
2127
+ expect(finalState).toHaveLength(1);
2128
+ expect(finalState[0]?.snapshot_content).toEqual({
2129
+ value: "tracked value",
2130
+ });
2131
+
2132
+ // Verify a change was created for the tracked mutation
2133
+ const changes = await lix.db
2134
+ .selectFrom("change")
2135
+ .where("entity_id", "=", "override-entity")
2136
+ .where("schema_key", "=", "mock_schema")
2137
+ .selectAll()
2138
+ .execute();
2139
+
2140
+ expect(changes.length).toBeGreaterThan(0);
2141
+ });
2142
+
2143
+ test("untracked state is persisted across lix sessions", async () => {
2144
+ const mockSchema: LixSchemaDefinition = {
2145
+ "x-lix-key": "mock_schema",
2146
+ "x-lix-version": "1.0",
2147
+ type: "object",
2148
+ additionalProperties: false,
2149
+ properties: {
2150
+ value: {
2151
+ type: "string",
2152
+ },
2153
+ },
2154
+ };
2155
+
2156
+ // First session - create and insert untracked state
2157
+ const lix1 = await openLix({});
2158
+
2159
+ await lix1.db
2160
+ .insertInto("stored_schema")
2161
+ .values({ value: mockSchema })
2162
+ .execute();
2163
+
2164
+ await lix1.db
2165
+ .insertInto("state_all")
2166
+ .values({
2167
+ entity_id: "persistent-entity",
2168
+ file_id: "test-file",
2169
+ schema_key: "mock_schema",
2170
+ plugin_key: "test_plugin",
2171
+ schema_version: "1.0",
2172
+ version_id: sql`(SELECT version_id FROM active_version)`,
2173
+ snapshot_content: {
2174
+ value: "persistent untracked value",
2175
+ },
2176
+ untracked: true,
2177
+ })
2178
+ .execute();
2179
+
2180
+ // Second session - verify untracked state persists
2181
+ const lix2 = await openLix({ blob: await lix1.toBlob() });
2182
+
2183
+ const persistedState = await lix2.db
2184
+ .selectFrom("state_all")
2185
+ .where("entity_id", "=", "persistent-entity")
2186
+ .selectAll()
2187
+ .execute();
2188
+
2189
+ expect(persistedState).toHaveLength(1);
2190
+ expect(persistedState[0]?.snapshot_content).toEqual({
2191
+ value: "persistent untracked value",
2192
+ });
2193
+
2194
+ await lix2.close();
2195
+ });
2196
+
2197
+ test("untracked state has highest priority in UNION (untracked > tracked > inherited)", async () => {
2198
+ const lix = await openLix({});
2199
+
2200
+ const mockSchema: LixSchemaDefinition = {
2201
+ "x-lix-key": "mock_schema",
2202
+ "x-lix-version": "1.0",
2203
+ type: "object",
2204
+ additionalProperties: false,
2205
+ properties: {
2206
+ value: {
2207
+ type: "string",
2208
+ },
2209
+ },
2210
+ };
2211
+
2212
+ await lix.db
2213
+ .insertInto("stored_schema")
2214
+ .values({ value: mockSchema })
2215
+ .execute();
2216
+
2217
+ // Step 1: Insert tracked state with "init"
2218
+ await lix.db
2219
+ .insertInto("state_all")
2220
+ .values({
2221
+ entity_id: "entity0",
2222
+ file_id: "test-file",
2223
+ schema_key: "mock_schema",
2224
+ plugin_key: "test_plugin",
2225
+ schema_version: "1.0",
2226
+ version_id: sql`(SELECT version_id FROM active_version)`,
2227
+ snapshot_content: {
2228
+ value: "init",
2229
+ },
2230
+ untracked: false,
2231
+ })
2232
+ .execute();
2233
+
2234
+ // Verify tracked state exists
2235
+ const afterInit = await lix.db
2236
+ .selectFrom("state_all")
2237
+ .where("entity_id", "=", "entity0")
2238
+ .selectAll()
2239
+ .execute();
2240
+
2241
+ expect(afterInit).toHaveLength(1);
2242
+ expect(afterInit[0]?.snapshot_content).toEqual({ value: "init" });
2243
+
2244
+ // Step 2: Update to untracked state with "update" (should NOT delete tracked state)
2245
+ await lix.db
2246
+ .updateTable("state_all")
2247
+ .set({
2248
+ snapshot_content: {
2249
+ value: "update",
2250
+ },
2251
+ untracked: true,
2252
+ })
2253
+ .where("entity_id", "=", "entity0")
2254
+ .where("schema_key", "=", "mock_schema")
2255
+ .execute();
2256
+
2257
+ // Step 3: Query should return untracked state "update" (highest priority)
2258
+ const afterUntrackedUpdate = await lix.db
2259
+ .selectFrom("state_all")
2260
+ .where("entity_id", "=", "entity0")
2261
+ .selectAll()
2262
+ .execute();
2263
+
2264
+ expect(afterUntrackedUpdate).toHaveLength(1);
2265
+ expect(afterUntrackedUpdate[0]?.snapshot_content).toEqual({
2266
+ value: "update",
2267
+ });
2268
+
2269
+ // Step 4: Update back to tracked state with "update2" (should delete untracked state)
2270
+ await lix.db
2271
+ .updateTable("state_all")
2272
+ .set({
2273
+ snapshot_content: {
2274
+ value: "update2",
2275
+ },
2276
+ untracked: false,
2277
+ })
2278
+ .where("entity_id", "=", "entity0")
2279
+ .where("schema_key", "=", "mock_schema")
2280
+ .execute();
2281
+
2282
+ // Step 5: Query should return tracked state "update2"
2283
+ const afterTrackedUpdate = await lix.db
2284
+ .selectFrom("state_all")
2285
+ .where("entity_id", "=", "entity0")
2286
+ .selectAll()
2287
+ .execute();
2288
+
2289
+ expect(afterTrackedUpdate).toHaveLength(1);
2290
+ expect(afterTrackedUpdate[0]?.snapshot_content).toEqual({ value: "update2" });
2291
+
2292
+ // Verify that a change was created for the final tracked mutation
2293
+ const changes = await lix.db
2294
+ .selectFrom("change")
2295
+ .where("entity_id", "=", "entity0")
2296
+ .where("schema_key", "=", "mock_schema")
2297
+ .selectAll()
2298
+ .execute();
2299
+
2300
+ expect(changes.length).toBeGreaterThan(0);
2301
+ });
2302
+
2303
+ test("untracked state overrides inherited state (untracked > inherited)", async () => {
2304
+ const lix = await openLix({});
2305
+
2306
+ const mockSchema: LixSchemaDefinition = {
2307
+ "x-lix-key": "mock_schema",
2308
+ "x-lix-version": "1.0",
2309
+ type: "object",
2310
+ additionalProperties: false,
2311
+ properties: {
2312
+ value: {
2313
+ type: "string",
2314
+ },
2315
+ },
2316
+ };
2317
+
2318
+ await lix.db
2319
+ .insertInto("stored_schema")
2320
+ .values({ value: mockSchema })
2321
+ .execute();
2322
+
2323
+ // Step 1: Insert entity in global version (will be inherited by child)
2324
+ await lix.db
2325
+ .insertInto("state_all")
2326
+ .values({
2327
+ entity_id: "inherited-entity",
2328
+ file_id: "test-file",
2329
+ schema_key: "mock_schema",
2330
+ plugin_key: "test_plugin",
2331
+ schema_version: "1.0",
2332
+ version_id: "global",
2333
+ snapshot_content: {
2334
+ value: "inherited value",
2335
+ },
2336
+ untracked: false,
2337
+ })
2338
+ .execute();
2339
+
2340
+ // Step 2: Create a child version that inherits from global
2341
+ const childVersion = await createVersion({ lix, name: "child-version" });
2342
+
2343
+ // Verify inheritance is set up correctly
2344
+ expect(childVersion.inherits_from_version_id).toBe("global");
2345
+
2346
+ // Step 3: Verify child initially sees inherited entity
2347
+ const inheritedState = await lix.db
2348
+ .selectFrom("state_all")
2349
+ .where("entity_id", "=", "inherited-entity")
2350
+ .where("version_id", "=", childVersion.id)
2351
+ .selectAll()
2352
+ .execute();
2353
+
2354
+ expect(inheritedState).toHaveLength(1);
2355
+ expect(inheritedState[0]?.snapshot_content).toEqual({
2356
+ value: "inherited value",
2357
+ });
2358
+ expect(inheritedState[0]?.inherited_from_version_id).toBe("global");
2359
+
2360
+ // Step 4: Add untracked state for same entity in child version
2361
+ await lix.db
2362
+ .insertInto("state_all")
2363
+ .values({
2364
+ entity_id: "inherited-entity",
2365
+ file_id: "test-file",
2366
+ schema_key: "mock_schema",
2367
+ plugin_key: "test_plugin",
2368
+ schema_version: "1.0",
2369
+ version_id: childVersion.id,
2370
+ snapshot_content: {
2371
+ value: "untracked override",
2372
+ },
2373
+ untracked: true,
2374
+ })
2375
+ .execute();
2376
+
2377
+ // Step 5: Query should return untracked state (higher priority than inherited)
2378
+ const finalState = await lix.db
2379
+ .selectFrom("state_all")
2380
+ .where("entity_id", "=", "inherited-entity")
2381
+ .where("version_id", "=", childVersion.id)
2382
+ .selectAll()
2383
+ .execute();
2384
+
2385
+ expect(finalState).toHaveLength(1);
2386
+ expect(finalState[0]?.snapshot_content).toEqual({
2387
+ value: "untracked override",
2388
+ });
2389
+ expect(finalState[0]?.inherited_from_version_id).toBe(null); // Should not be inherited anymore
2390
+ expect(finalState[0]?.version_id).toBe(childVersion.id);
2391
+
2392
+ // Step 6: Verify the inherited entity still exists in global version (unchanged)
2393
+ const globalState = await lix.db
2394
+ .selectFrom("state_all")
2395
+ .where("entity_id", "=", "inherited-entity")
2396
+ .where("version_id", "=", "global")
2397
+ .selectAll()
2398
+ .execute();
2399
+
2400
+ expect(globalState).toHaveLength(1);
2401
+ expect(globalState[0]?.snapshot_content).toEqual({
2402
+ value: "inherited value",
2403
+ });
2404
+ expect(globalState[0]?.inherited_from_version_id).toBe(null);
2405
+
2406
+ // Step 7: No changes should be created for untracked mutations
2407
+ const changes = await lix.db
2408
+ .selectFrom("change")
2409
+ .where("entity_id", "=", "inherited-entity")
2410
+ .where("schema_key", "=", "mock_schema")
2411
+ .selectAll()
2412
+ .execute();
2413
+
2414
+ // Should only have the original change from global version, not the untracked one
2415
+ expect(changes).toHaveLength(1);
2416
+ });