@lix-js/sdk 0.0.1 → 0.1.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 (278) hide show
  1. package/LICENSE +21 -0
  2. package/dist/change/apply-changes.js +9 -9
  3. package/dist/change/apply-changes.js.map +1 -1
  4. package/dist/change/apply-changes.test.js +5 -5
  5. package/dist/change/apply-changes.test.js.map +1 -1
  6. package/dist/database/apply-schema.d.ts.map +1 -1
  7. package/dist/database/apply-schema.js +20 -72
  8. package/dist/database/apply-schema.js.map +1 -1
  9. package/dist/database/execute-sync.test.js +3 -3
  10. package/dist/database/execute-sync.test.js.map +1 -1
  11. package/dist/database/init-db.d.ts.map +1 -1
  12. package/dist/database/init-db.js +18 -3
  13. package/dist/database/init-db.js.map +1 -1
  14. package/dist/database/init-db.test.js +128 -17
  15. package/dist/database/init-db.test.js.map +1 -1
  16. package/dist/database/kysely-plugin/parse-jsonb-plugin-v1.d.ts.map +1 -1
  17. package/dist/database/kysely-plugin/parse-jsonb-plugin-v1.js +5 -2
  18. package/dist/database/kysely-plugin/parse-jsonb-plugin-v1.js.map +1 -1
  19. package/dist/database/mutation-log/database-schema.d.ts.map +1 -1
  20. package/dist/database/mutation-log/database-schema.js +1 -3
  21. package/dist/database/mutation-log/database-schema.js.map +1 -1
  22. package/dist/database/nano-id.d.ts +21 -0
  23. package/dist/database/nano-id.d.ts.map +1 -0
  24. package/dist/database/nano-id.js +58 -0
  25. package/dist/database/nano-id.js.map +1 -0
  26. package/dist/database/nano-id.test.d.ts +2 -0
  27. package/dist/database/nano-id.test.d.ts.map +1 -0
  28. package/dist/database/nano-id.test.js +13 -0
  29. package/dist/database/nano-id.test.js.map +1 -0
  30. package/dist/database/schema.d.ts +15 -23
  31. package/dist/database/schema.d.ts.map +1 -1
  32. package/dist/discussion/create-comment.d.ts +0 -2
  33. package/dist/discussion/create-comment.d.ts.map +1 -1
  34. package/dist/discussion/create-comment.js +0 -1
  35. package/dist/discussion/create-comment.js.map +1 -1
  36. package/dist/discussion/create-discussion.d.ts +3 -5
  37. package/dist/discussion/create-discussion.d.ts.map +1 -1
  38. package/dist/discussion/create-discussion.js +4 -5
  39. package/dist/discussion/create-discussion.js.map +1 -1
  40. package/dist/discussion/create-discussion.test.js +8 -34
  41. package/dist/discussion/create-discussion.test.js.map +1 -1
  42. package/dist/file-queue/file-handlers.d.ts +24 -0
  43. package/dist/file-queue/file-handlers.d.ts.map +1 -0
  44. package/dist/file-queue/file-handlers.js +209 -0
  45. package/dist/file-queue/file-handlers.js.map +1 -0
  46. package/dist/file-queue/file-queue-process.d.ts +5 -0
  47. package/dist/file-queue/file-queue-process.d.ts.map +1 -0
  48. package/dist/file-queue/file-queue-process.js +85 -0
  49. package/dist/file-queue/file-queue-process.js.map +1 -0
  50. package/dist/file-queue/file-queue-process.test.d.ts +2 -0
  51. package/dist/file-queue/file-queue-process.test.d.ts.map +1 -0
  52. package/dist/file-queue/file-queue-process.test.js +373 -0
  53. package/dist/file-queue/file-queue-process.test.js.map +1 -0
  54. package/dist/file-queue/file-queue-settled.d.ts +13 -0
  55. package/dist/file-queue/file-queue-settled.d.ts.map +1 -0
  56. package/dist/file-queue/file-queue-settled.js +25 -0
  57. package/dist/file-queue/file-queue-settled.js.map +1 -0
  58. package/dist/file-queue/file-queue-settled.test.d.ts +2 -0
  59. package/dist/file-queue/file-queue-settled.test.d.ts.map +1 -0
  60. package/dist/file-queue/file-queue-settled.test.js +47 -0
  61. package/dist/file-queue/file-queue-settled.test.js.map +1 -0
  62. package/dist/file-queue/index.d.ts +2 -0
  63. package/dist/file-queue/index.d.ts.map +1 -0
  64. package/dist/file-queue/index.js +2 -0
  65. package/dist/file-queue/index.js.map +1 -0
  66. package/dist/file-queue/with-skip-file-queue.d.ts +3 -0
  67. package/dist/file-queue/with-skip-file-queue.d.ts.map +1 -0
  68. package/dist/file-queue/with-skip-file-queue.js +26 -0
  69. package/dist/file-queue/with-skip-file-queue.js.map +1 -0
  70. package/dist/file-queue/with-skip-file-queue.test.d.ts +2 -0
  71. package/dist/file-queue/with-skip-file-queue.test.d.ts.map +1 -0
  72. package/dist/file-queue/with-skip-file-queue.test.js +138 -0
  73. package/dist/file-queue/with-skip-file-queue.test.js.map +1 -0
  74. package/dist/index.d.ts +2 -2
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +2 -2
  77. package/dist/index.js.map +1 -1
  78. package/dist/key-value/database-schema.d.ts +11 -2
  79. package/dist/key-value/database-schema.d.ts.map +1 -1
  80. package/dist/key-value/database-schema.js +7 -4
  81. package/dist/key-value/database-schema.js.map +1 -1
  82. package/dist/key-value/database-schema.test.js +21 -5
  83. package/dist/key-value/database-schema.test.js.map +1 -1
  84. package/dist/lix/close-lix.d.ts +8 -0
  85. package/dist/lix/close-lix.d.ts.map +1 -0
  86. package/dist/lix/close-lix.js +7 -0
  87. package/dist/lix/close-lix.js.map +1 -0
  88. package/dist/lix/index.d.ts +1 -0
  89. package/dist/lix/index.d.ts.map +1 -1
  90. package/dist/lix/index.js +1 -0
  91. package/dist/lix/index.js.map +1 -1
  92. package/dist/lix/merge.js +3 -3
  93. package/dist/lix/merge.js.map +1 -1
  94. package/dist/lix/merge.test.js +7 -18
  95. package/dist/lix/merge.test.js.map +1 -1
  96. package/dist/lix/new-lix.d.ts.map +1 -1
  97. package/dist/lix/new-lix.js +2 -3
  98. package/dist/lix/new-lix.js.map +1 -1
  99. package/dist/lix/open-lix-in-memory.test.js +2 -1
  100. package/dist/lix/open-lix-in-memory.test.js.map +1 -1
  101. package/dist/lix/open-lix.d.ts +3 -5
  102. package/dist/lix/open-lix.d.ts.map +1 -1
  103. package/dist/lix/open-lix.js +4 -18
  104. package/dist/lix/open-lix.js.map +1 -1
  105. package/dist/lix/open-lix.test.js +16 -7
  106. package/dist/lix/open-lix.test.js.map +1 -1
  107. package/dist/lix/to-blob.d.ts +11 -0
  108. package/dist/lix/to-blob.d.ts.map +1 -0
  109. package/dist/lix/to-blob.js +11 -0
  110. package/dist/lix/to-blob.js.map +1 -0
  111. package/dist/own-change-control/apply-own-change.d.ts +10 -0
  112. package/dist/own-change-control/apply-own-change.d.ts.map +1 -0
  113. package/dist/own-change-control/apply-own-change.js +69 -0
  114. package/dist/own-change-control/apply-own-change.js.map +1 -0
  115. package/dist/own-change-control/apply-own-change.test.d.ts +2 -0
  116. package/dist/own-change-control/apply-own-change.test.d.ts.map +1 -0
  117. package/dist/own-change-control/apply-own-change.test.js +297 -0
  118. package/dist/own-change-control/apply-own-change.test.js.map +1 -0
  119. package/dist/own-change-control/change-controlled-tables.d.ts +60 -0
  120. package/dist/own-change-control/change-controlled-tables.d.ts.map +1 -0
  121. package/dist/own-change-control/change-controlled-tables.js +70 -0
  122. package/dist/own-change-control/change-controlled-tables.js.map +1 -0
  123. package/dist/own-change-control/change-controlled-tables.test.d.ts +2 -0
  124. package/dist/own-change-control/change-controlled-tables.test.d.ts.map +1 -0
  125. package/dist/own-change-control/change-controlled-tables.test.js +48 -0
  126. package/dist/own-change-control/change-controlled-tables.test.js.map +1 -0
  127. package/dist/own-change-control/database-triggers.d.ts +5 -0
  128. package/dist/own-change-control/database-triggers.d.ts.map +1 -0
  129. package/dist/own-change-control/database-triggers.js +135 -0
  130. package/dist/own-change-control/database-triggers.js.map +1 -0
  131. package/dist/own-change-control/database-triggers.test.d.ts +2 -0
  132. package/dist/own-change-control/database-triggers.test.d.ts.map +1 -0
  133. package/dist/own-change-control/database-triggers.test.js +214 -0
  134. package/dist/own-change-control/database-triggers.test.js.map +1 -0
  135. package/dist/own-change-control/index.d.ts +2 -0
  136. package/dist/own-change-control/index.d.ts.map +1 -0
  137. package/dist/own-change-control/index.js +2 -0
  138. package/dist/own-change-control/index.js.map +1 -0
  139. package/dist/own-change-control/with-skip-own-change-control.d.ts +3 -0
  140. package/dist/own-change-control/with-skip-own-change-control.d.ts.map +1 -0
  141. package/dist/own-change-control/with-skip-own-change-control.js +28 -0
  142. package/dist/own-change-control/with-skip-own-change-control.js.map +1 -0
  143. package/dist/own-change-control/with-skip-own-change-control.test.d.ts +2 -0
  144. package/dist/own-change-control/with-skip-own-change-control.test.d.ts.map +1 -0
  145. package/dist/own-change-control/with-skip-own-change-control.test.js +49 -0
  146. package/dist/own-change-control/with-skip-own-change-control.test.js.map +1 -0
  147. package/dist/own-entity-change-control/apply-own-entity-change.js +2 -2
  148. package/dist/own-entity-change-control/apply-own-entity-change.js.map +1 -1
  149. package/dist/own-entity-change-control/apply-own-entity-change.test.js +9 -9
  150. package/dist/own-entity-change-control/apply-own-entity-change.test.js.map +1 -1
  151. package/dist/own-entity-change-control/database-triggers.js +6 -6
  152. package/dist/own-entity-change-control/database-triggers.js.map +1 -1
  153. package/dist/own-entity-change-control/database-triggers.test.js +1 -1
  154. package/dist/own-entity-change-control/database-triggers.test.js.map +1 -1
  155. package/dist/query-filter/version-change-in-difference.test.js +37 -29
  156. package/dist/query-filter/version-change-in-difference.test.js.map +1 -1
  157. package/dist/query-filter/version-change-in-symmetric-difference.test.js +37 -39
  158. package/dist/query-filter/version-change-in-symmetric-difference.test.js.map +1 -1
  159. package/dist/server-api-handler/environment/create-in-memory-environment.d.ts.map +1 -1
  160. package/dist/server-api-handler/environment/create-in-memory-environment.js +7 -3
  161. package/dist/server-api-handler/environment/create-in-memory-environment.js.map +1 -1
  162. package/dist/server-api-handler/environment/create-in-memory-environment.test.js +8 -7
  163. package/dist/server-api-handler/environment/create-in-memory-environment.test.js.map +1 -1
  164. package/dist/server-api-handler/routes/get-v1.d.ts.map +1 -1
  165. package/dist/server-api-handler/routes/get-v1.js +1 -2
  166. package/dist/server-api-handler/routes/get-v1.js.map +1 -1
  167. package/dist/server-api-handler/routes/get-v1.test.js +6 -5
  168. package/dist/server-api-handler/routes/get-v1.test.js.map +1 -1
  169. package/dist/server-api-handler/routes/new-v1.d.ts.map +1 -1
  170. package/dist/server-api-handler/routes/new-v1.js +3 -1
  171. package/dist/server-api-handler/routes/new-v1.js.map +1 -1
  172. package/dist/server-api-handler/routes/new-v1.test.js +2 -1
  173. package/dist/server-api-handler/routes/new-v1.test.js.map +1 -1
  174. package/dist/server-api-handler/routes/pull-v1.test.js +4 -3
  175. package/dist/server-api-handler/routes/pull-v1.test.js.map +1 -1
  176. package/dist/server-api-handler/routes/push-v1.test.js +5 -4
  177. package/dist/server-api-handler/routes/push-v1.test.js.map +1 -1
  178. package/dist/sync/pull-from-server.d.ts.map +1 -1
  179. package/dist/sync/pull-from-server.js +0 -2
  180. package/dist/sync/pull-from-server.js.map +1 -1
  181. package/dist/sync/pull-from-server.test.js +29 -14
  182. package/dist/sync/pull-from-server.test.js.map +1 -1
  183. package/dist/sync/push-to-server.test.js +17 -13
  184. package/dist/sync/push-to-server.test.js.map +1 -1
  185. package/dist/sync/sync-process.d.ts +2 -4
  186. package/dist/sync/sync-process.d.ts.map +1 -1
  187. package/dist/sync/sync-process.js +4 -9
  188. package/dist/sync/sync-process.js.map +1 -1
  189. package/dist/sync/sync-process.test.js +26 -38
  190. package/dist/sync/sync-process.test.js.map +1 -1
  191. package/dist/version/create-version.d.ts +5 -5
  192. package/dist/version/create-version.d.ts.map +1 -1
  193. package/dist/version/create-version.js +23 -11
  194. package/dist/version/create-version.js.map +1 -1
  195. package/dist/version/create-version.test.js +2 -2
  196. package/dist/version/create-version.test.js.map +1 -1
  197. package/dist/version/merge-version.d.ts.map +1 -1
  198. package/dist/version/merge-version.js +16 -26
  199. package/dist/version/merge-version.js.map +1 -1
  200. package/dist/version/switch-version.js +3 -3
  201. package/dist/version/switch-version.js.map +1 -1
  202. package/dist/version/switch-version.test.js +12 -15
  203. package/dist/version/switch-version.test.js.map +1 -1
  204. package/dist/version/update-changes-in-version.d.ts.map +1 -1
  205. package/dist/version/update-changes-in-version.js +11 -31
  206. package/dist/version/update-changes-in-version.js.map +1 -1
  207. package/node_modules/@lix-js/server-api-schema/CHANGELOG.md +9 -0
  208. package/node_modules/@lix-js/server-api-schema/LICENSE +21 -0
  209. package/node_modules/@lix-js/server-api-schema/dist/schema.js +0 -0
  210. package/node_modules/@lix-js/server-api-schema/package.json +2 -2
  211. package/node_modules/sqlite-wasm-kysely/LICENSE +21 -0
  212. package/package.json +4 -4
  213. package/src/change/apply-changes.test.ts +7 -7
  214. package/src/change/apply-changes.ts +9 -9
  215. package/src/database/apply-schema.ts +20 -73
  216. package/src/database/execute-sync.test.ts +3 -3
  217. package/src/database/init-db.test.ts +163 -19
  218. package/src/database/init-db.ts +20 -3
  219. package/src/database/kysely-plugin/parse-jsonb-plugin-v1.ts +9 -2
  220. package/src/database/mutation-log/database-schema.ts +1 -3
  221. package/src/database/nano-id.test.ts +15 -0
  222. package/src/database/nano-id.ts +72 -0
  223. package/src/database/schema.ts +15 -24
  224. package/src/discussion/create-comment.ts +0 -3
  225. package/src/discussion/create-discussion.test.ts +8 -39
  226. package/src/discussion/create-discussion.ts +6 -9
  227. package/src/{change-queue → file-queue}/file-handlers.ts +27 -27
  228. package/src/{change-queue/init-change-queue.test.ts → file-queue/file-queue-process.test.ts} +24 -24
  229. package/src/{change-queue/init-change-queue.ts → file-queue/file-queue-process.ts} +18 -16
  230. package/src/{change-queue/change-queue-settled.test.ts → file-queue/file-queue-settled.test.ts} +12 -12
  231. package/src/{change-queue/change-queue-settled.ts → file-queue/file-queue-settled.ts} +4 -4
  232. package/src/file-queue/index.ts +1 -0
  233. package/src/{change-queue/with-skip-change-queue.test.ts → file-queue/with-skip-file-queue.test.ts} +9 -9
  234. package/src/{change-queue/with-skip-change-queue.ts → file-queue/with-skip-file-queue.ts} +3 -3
  235. package/src/index.ts +2 -2
  236. package/src/key-value/database-schema.test.ts +26 -5
  237. package/src/key-value/database-schema.ts +18 -6
  238. package/src/lix/close-lix.ts +8 -0
  239. package/src/lix/index.ts +1 -0
  240. package/src/lix/merge.test.ts +7 -19
  241. package/src/lix/merge.ts +4 -4
  242. package/src/lix/new-lix.ts +2 -3
  243. package/src/lix/open-lix-in-memory.test.ts +5 -1
  244. package/src/lix/open-lix.test.ts +19 -7
  245. package/src/lix/open-lix.ts +7 -24
  246. package/src/lix/to-blob.ts +14 -0
  247. package/src/{own-entity-change-control/apply-own-entity-change.test.ts → own-change-control/apply-own-change.test.ts} +27 -31
  248. package/src/{own-entity-change-control/apply-own-entity-change.ts → own-change-control/apply-own-change.ts} +3 -3
  249. package/src/{own-entity-change-control → own-change-control}/change-controlled-tables.ts +0 -1
  250. package/src/{own-entity-change-control → own-change-control}/database-triggers.test.ts +7 -7
  251. package/src/{own-entity-change-control → own-change-control}/database-triggers.ts +11 -11
  252. package/src/{own-entity-change-control → own-change-control}/with-skip-own-change-control.ts +6 -2
  253. package/src/query-filter/version-change-in-difference.test.ts +41 -32
  254. package/src/query-filter/version-change-in-symmetric-difference.test.ts +41 -42
  255. package/src/server-api-handler/environment/create-in-memory-environment.test.ts +8 -7
  256. package/src/server-api-handler/environment/create-in-memory-environment.ts +7 -3
  257. package/src/server-api-handler/routes/get-v1.test.ts +6 -5
  258. package/src/server-api-handler/routes/get-v1.ts +1 -3
  259. package/src/server-api-handler/routes/new-v1.test.ts +2 -1
  260. package/src/server-api-handler/routes/new-v1.ts +3 -1
  261. package/src/server-api-handler/routes/pull-v1.test.ts +4 -3
  262. package/src/server-api-handler/routes/push-v1.test.ts +5 -4
  263. package/src/sync/pull-from-server.test.ts +29 -14
  264. package/src/sync/pull-from-server.ts +0 -2
  265. package/src/sync/push-to-server.test.ts +19 -15
  266. package/src/sync/sync-process.test.ts +37 -43
  267. package/src/sync/sync-process.ts +6 -18
  268. package/src/version/create-version.test.ts +2 -2
  269. package/src/version/create-version.ts +24 -12
  270. package/src/version/merge-version.ts +18 -26
  271. package/src/version/switch-version.test.ts +12 -15
  272. package/src/version/switch-version.ts +3 -3
  273. package/src/version/update-changes-in-version.ts +11 -30
  274. package/node_modules/@lix-js/server-api-schema/dist/schema.d.ts +0 -384
  275. package/src/change-queue/index.ts +0 -1
  276. /package/src/{own-entity-change-control → own-change-control}/change-controlled-tables.test.ts +0 -0
  277. /package/src/{own-entity-change-control → own-change-control}/index.ts +0 -0
  278. /package/src/{own-entity-change-control → own-change-control}/with-skip-own-change-control.test.ts +0 -0
@@ -1,12 +1,12 @@
1
1
  import { test, expect } from "vitest";
2
2
  import { openLixInMemory } from "../lix/open-lix-in-memory.js";
3
- import { changeQueueSettled } from "./change-queue-settled.js";
3
+ import { fileQueueSettled } from "./file-queue-settled.js";
4
4
 
5
- test("should wait until the change queue is settled", async () => {
5
+ test("should wait until the file queue is settled", async () => {
6
6
  const lix = await openLixInMemory({});
7
7
 
8
8
  await lix.db
9
- .insertInto("change_queue")
9
+ .insertInto("file_queue")
10
10
  .values([
11
11
  {
12
12
  id: 1,
@@ -25,31 +25,31 @@ test("should wait until the change queue is settled", async () => {
25
25
  ])
26
26
  .execute();
27
27
 
28
- // Start a background task to remove entries from the change_queue after a delay
28
+ // Start a background task to remove entries from the file_queue after a delay
29
29
  setTimeout(async () => {
30
- await lix.db.deleteFrom("change_queue").where("id", "=", 1).execute();
31
- await lix.db.deleteFrom("change_queue").where("id", "=", 2).execute();
30
+ await lix.db.deleteFrom("file_queue").where("id", "=", 1).execute();
31
+ await lix.db.deleteFrom("file_queue").where("id", "=", 2).execute();
32
32
  }, 110);
33
33
 
34
- await changeQueueSettled({ lix });
34
+ await fileQueueSettled({ lix });
35
35
 
36
36
  const remainingEntries = await lix.db
37
- .selectFrom("change_queue")
37
+ .selectFrom("file_queue")
38
38
  .selectAll()
39
39
  .execute();
40
40
 
41
41
  expect(remainingEntries).toEqual([]);
42
42
  });
43
43
 
44
- test("should return immediately if the change queue is already empty", async () => {
44
+ test("should return immediately if the file queue is already empty", async () => {
45
45
  const lix = await openLixInMemory({});
46
46
 
47
- await lix.db.deleteFrom("change_queue").execute();
47
+ await lix.db.deleteFrom("file_queue").execute();
48
48
 
49
- await changeQueueSettled({ lix });
49
+ await fileQueueSettled({ lix });
50
50
 
51
51
  const remainingEntries = await lix.db
52
- .selectFrom("change_queue")
52
+ .selectFrom("file_queue")
53
53
  .selectAll()
54
54
  .execute();
55
55
  expect(remainingEntries).toEqual([]);
@@ -1,21 +1,21 @@
1
1
  import type { Lix } from "../lix/open-lix.js";
2
2
 
3
3
  /**
4
- * Waits until the change queue is settled.
4
+ * Waits until the file queue is settled.
5
5
  *
6
6
  * @example
7
7
  * ```ts
8
- * await changeQueueSettled({ lix });
8
+ * await fileQueueSettled({ lix });
9
9
  * ```
10
10
  */
11
- export async function changeQueueSettled(args: {
11
+ export async function fileQueueSettled(args: {
12
12
  lix: Pick<Lix, "db">;
13
13
  }): Promise<void> {
14
14
  let hasEntries = true;
15
15
 
16
16
  while (hasEntries) {
17
17
  const entries = await args.lix.db
18
- .selectFrom("change_queue")
18
+ .selectFrom("file_queue")
19
19
  .selectAll()
20
20
  .limit(1)
21
21
  .execute();
@@ -0,0 +1 @@
1
+ export { fileQueueSettled } from "./file-queue-settled.js";
@@ -1,10 +1,10 @@
1
1
  import { expect, test } from "vitest";
2
2
  import type { LixPlugin } from "../plugin/lix-plugin.js";
3
3
  import { openLixInMemory } from "../lix/open-lix-in-memory.js";
4
- import { changeQueueSettled } from "./change-queue-settled.js";
5
- import { withSkipChangeQueue } from "./with-skip-change-queue.js";
4
+ import { fileQueueSettled } from "./file-queue-settled.js";
5
+ import { withSkipFileQueue } from "./with-skip-file-queue.js";
6
6
 
7
- test("skipping the change queue should be possible", async () => {
7
+ test("skipping the file queue should be possible", async () => {
8
8
  const mockPlugin: LixPlugin = {
9
9
  key: "mock-plugin",
10
10
  detectChangesGlob: "*",
@@ -38,7 +38,7 @@ test("skipping the change queue should be possible", async () => {
38
38
  })
39
39
  .execute();
40
40
 
41
- await changeQueueSettled({ lix });
41
+ await fileQueueSettled({ lix });
42
42
 
43
43
  const changes0 = await lix.db
44
44
  .selectFrom("change")
@@ -50,7 +50,7 @@ test("skipping the change queue should be possible", async () => {
50
50
  expect(changes0).toHaveLength(1);
51
51
  expect(changes0[0]?.content).toEqual({ text: "update0" });
52
52
 
53
- await withSkipChangeQueue(lix.db, async (trx) => {
53
+ await withSkipFileQueue(lix.db, async (trx) => {
54
54
  await trx
55
55
  .updateTable("file")
56
56
  .set({
@@ -60,7 +60,7 @@ test("skipping the change queue should be possible", async () => {
60
60
  .execute();
61
61
  });
62
62
 
63
- await changeQueueSettled({ lix });
63
+ await fileQueueSettled({ lix });
64
64
 
65
65
  const changes1 = await lix.db
66
66
  .selectFrom("change")
@@ -74,7 +74,7 @@ test("skipping the change queue should be possible", async () => {
74
74
  expect(changes1[0]?.content).toEqual({ text: "update0" });
75
75
  });
76
76
 
77
- test("skipping the change queue should be possible with multiple changes", async () => {
77
+ test("skipping the file queue should be possible with multiple changes", async () => {
78
78
  const mockPlugin: LixPlugin = {
79
79
  key: "mock-plugin",
80
80
  detectChangesGlob: "*",
@@ -124,7 +124,7 @@ test("skipping the change queue should be possible with multiple changes", async
124
124
  .execute();
125
125
  }
126
126
  for (const update of last50Updates) {
127
- await withSkipChangeQueue(trx, async (trx) => {
127
+ await withSkipFileQueue(trx, async (trx) => {
128
128
  await trx
129
129
  .updateTable("file")
130
130
  .set({
@@ -136,7 +136,7 @@ test("skipping the change queue should be possible with multiple changes", async
136
136
  }
137
137
  });
138
138
 
139
- await changeQueueSettled({ lix });
139
+ await fileQueueSettled({ lix });
140
140
 
141
141
  const file = await lix.db
142
142
  .selectFrom("file")
@@ -1,12 +1,12 @@
1
1
  import type { Lix } from "../lix/open-lix.js";
2
2
 
3
- export async function withSkipChangeQueue<T>(
3
+ export async function withSkipFileQueue<T>(
4
4
  db: Lix["db"],
5
5
  operation: (trx: Lix["db"]) => Promise<T>
6
6
  ): Promise<T> {
7
7
  const executeInTransaction = async (trx: Lix["db"]) => {
8
8
  const queryEntryBefore = await trx
9
- .selectFrom("change_queue")
9
+ .selectFrom("file_queue")
10
10
  .selectAll()
11
11
  .orderBy("id desc")
12
12
  .executeTakeFirst();
@@ -18,7 +18,7 @@ export async function withSkipChangeQueue<T>(
18
18
  // the queue entry before the transaction
19
19
 
20
20
  await trx
21
- .deleteFrom("change_queue")
21
+ .deleteFrom("file_queue")
22
22
  .where("id", ">", queryEntryBefore?.id ?? 0)
23
23
  .execute();
24
24
 
package/src/index.ts CHANGED
@@ -2,13 +2,13 @@ export * from "./account/index.js";
2
2
  export * from "./change/index.js";
3
3
  export * from "./change-set/index.js";
4
4
  export * from "./change-conflict/index.js";
5
- export * from "./change-queue/index.js";
5
+ export * from "./file-queue/index.js";
6
6
  export * from "./change-schema/index.js";
7
7
  export * from "./database/index.js";
8
8
  export * from "./discussion/index.js";
9
9
  export * from "./file/index.js";
10
10
  export * from "./lix/index.js";
11
- export * from "./own-entity-change-control/index.js";
11
+ export * from "./own-change-control/index.js";
12
12
  export * from "./plugin/index.js";
13
13
  export * from "./query-filter/index.js";
14
14
  export * from "./server-api-handler/index.js";
@@ -1,7 +1,6 @@
1
1
  import { sql } from "kysely";
2
2
  import { expect, test } from "vitest";
3
3
  import { openLixInMemory } from "../lix/open-lix-in-memory.js";
4
- import { validate as validateUuid } from "uuid";
5
4
 
6
5
  test("string values are accepted", async () => {
7
6
  const lix = await openLixInMemory({});
@@ -94,7 +93,8 @@ test("using json as value should work", async () => {
94
93
  });
95
94
  });
96
95
 
97
- test("it should default add a uuid lix_id if not exits", async () => {
96
+ // 1919T IDs needed, in order to have a 1% probability of at least one collision.
97
+ test("it should default add nano_id(18) for the lix_id if not exits", async () => {
98
98
  const lix = await openLixInMemory({});
99
99
 
100
100
  const result = await lix.db
@@ -103,17 +103,38 @@ test("it should default add a uuid lix_id if not exits", async () => {
103
103
  .selectAll()
104
104
  .executeTakeFirstOrThrow();
105
105
 
106
- expect(validateUuid(result.value)).toBe(true);
106
+ expect(result.value).toHaveLength(18);
107
107
  });
108
108
 
109
- test("default value for #lix_sync to reduce conditional logic (the key is always set)", async () => {
109
+ test("default value for lix_sync to reduce conditional logic (the key is always set)", async () => {
110
110
  const lix = await openLixInMemory({});
111
111
 
112
112
  const result = await lix.db
113
113
  .selectFrom("key_value")
114
- .where("key", "=", "#lix_sync")
114
+ .where("key", "=", "lix_sync")
115
115
  .selectAll()
116
116
  .executeTakeFirstOrThrow();
117
117
 
118
118
  expect(result.value).toBe("false");
119
119
  });
120
+
121
+ test("skip_change_control should default to false", async () => {
122
+ const lix = await openLixInMemory({});
123
+
124
+ const result = await lix.db
125
+ .insertInto("key_value")
126
+ .values({ key: "mock_key", value: "mock_value" })
127
+ .returningAll()
128
+ .executeTakeFirstOrThrow();
129
+
130
+ expect(result.skip_change_control).toBeFalsy();
131
+
132
+ const updated = await lix.db
133
+ .updateTable("key_value")
134
+ .set({ skip_change_control: true })
135
+ .where("key", "=", "mock_key")
136
+ .returningAll()
137
+ .executeTakeFirstOrThrow();
138
+
139
+ expect(updated.skip_change_control).toBeTruthy();
140
+ });
@@ -1,4 +1,4 @@
1
- import type { Insertable, Selectable, Updateable } from "kysely";
1
+ import type { Generated, Insertable, Selectable, Updateable } from "kysely";
2
2
  import type { SqliteDatabase } from "sqlite-wasm-kysely";
3
3
 
4
4
  export function applyKeyValueDatabaseSchema(
@@ -7,17 +7,20 @@ export function applyKeyValueDatabaseSchema(
7
7
  return sqlite.exec`
8
8
  CREATE TABLE IF NOT EXISTS key_value (
9
9
  key TEXT PRIMARY KEY,
10
- value TEXT NOT NULL
10
+ value TEXT NOT NULL,
11
+
12
+ -- Options
13
+ skip_change_control INT DEFAULT FALSE
11
14
  ) STRICT;
12
15
 
13
16
  INSERT OR IGNORE INTO key_value (key, value)
14
- VALUES ('lix_id', uuid_v4());
17
+ VALUES ('lix_id', nano_id(18));
15
18
 
16
19
  -- default value for lix sync to false
17
20
  -- if not exist to remove conditional logic
18
21
  -- if the key exists or not
19
- INSERT OR IGNORE INTO key_value (key, value)
20
- VALUES ('#lix_sync', 'false');
22
+ INSERT OR IGNORE INTO key_value (key, value, skip_change_control)
23
+ VALUES ('lix_sync', 'false', 1);
21
24
  `;
22
25
  }
23
26
 
@@ -45,9 +48,18 @@ export type KeyValueTable = {
45
48
  *
46
49
  */
47
50
  value: string;
51
+ /**
52
+ * If `true`, the key-value pair is not tracked with own change control.
53
+ *
54
+ * Carefull (!) when querying the database. The return value will be `0` or `1`.
55
+ * SQLite does not have a boolean select type https://www.sqlite.org/datatype3.html.
56
+ *
57
+ * @default false
58
+ */
59
+ skip_change_control: Generated<boolean>;
48
60
  };
49
61
 
50
- type PredefinedKeys = "lix_id" | "lix_server_url" | "#lix_sync";
62
+ type PredefinedKeys = "lix_id" | "lix_server_url" | "lix_sync";
51
63
  // The string & {} ensures TypeScript recognizes KeyValueKeys
52
64
  // as a superset of string, preventing conflicts when using other string values.
53
65
  type KeyType = string & {};
@@ -0,0 +1,8 @@
1
+ import type { Lix } from "./open-lix.js";
2
+
3
+ /**
4
+ * Closes the lix.
5
+ */
6
+ export async function closeLix(args: { lix: Pick<Lix, "db"> }): Promise<void> {
7
+ await args.lix.db.destroy();
8
+ }
package/src/lix/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { type Lix, openLix } from "./open-lix.js";
2
2
  export { openLixInMemory } from "./open-lix-in-memory.js";
3
3
  export { newLixFile } from "./new-lix.js";
4
+ export { toBlob } from "./to-blob.js";
4
5
  // not exporting merge for api stability milestone
5
6
  // will need an overhaul to be stable
6
7
  // export { merge } from "./merge.js";
@@ -13,7 +13,8 @@ import { mockJsonSnapshot } from "../snapshot/mock-json-snapshot.js";
13
13
  import { createChangeSet } from "../change-set/create-change-set.js";
14
14
  import { createDiscussion } from "../discussion/create-discussion.js";
15
15
  import { createComment } from "../discussion/create-comment.js";
16
- import { changeQueueSettled } from "../change-queue/change-queue-settled.js";
16
+ import { fileQueueSettled } from "../file-queue/file-queue-settled.js";
17
+ import { toBlob } from "./to-blob.js";
17
18
 
18
19
  test("it should copy changes from the sourceLix into the targetLix that do not exist in targetLix yet", async () => {
19
20
  const mockSnapshots = [
@@ -441,7 +442,7 @@ test.todo("it should apply changes that are not conflicting", async () => {
441
442
  })
442
443
  .execute();
443
444
 
444
- await changeQueueSettled({ lix: targetLix });
445
+ await fileQueueSettled({ lix: targetLix });
445
446
 
446
447
  await merge({ sourceLix, targetLix });
447
448
  const changes = await targetLix.db
@@ -687,11 +688,11 @@ test("it should copy discussion and related comments and mappings", async () =>
687
688
  })
688
689
  .execute();
689
690
 
690
- await changeQueueSettled({ lix: lix1 });
691
+ await fileQueueSettled({ lix: lix1 });
691
692
 
692
693
  // The files have to be there before we merge
693
694
  const lix2 = await openLixInMemory({
694
- blob: await lix1.toBlob(),
695
+ blob: await toBlob({ lix: lix1 }),
695
696
  providePlugins: [mockPlugin],
696
697
  });
697
698
 
@@ -720,17 +721,10 @@ test("it should copy discussion and related comments and mappings", async () =>
720
721
  ])
721
722
  );
722
723
 
723
- // TODO how do know which author to use for the discussion - we can have multiple active accounts?
724
- const currentAuthorLix1 = await lix1.db
725
- .selectFrom("active_account")
726
- .selectAll()
727
- .executeTakeFirstOrThrow();
728
-
729
724
  await createDiscussion({
730
725
  lix: lix1,
731
726
  changeSet: await createChangeSet({ lix: lix1, changes: [changes[0]!] }),
732
- content: "comment on a change",
733
- createdBy: { id: currentAuthorLix1.id },
727
+ firstComment: { content: "comment on a change" },
734
728
  });
735
729
 
736
730
  await merge({ sourceLix: lix1, targetLix: lix2 });
@@ -747,21 +741,15 @@ test("it should copy discussion and related comments and mappings", async () =>
747
741
  // lix 2 has no comments yet so after lix 1 into 2 we should be in sync
748
742
  expect(commentsLix1).toEqual(commentsLix2AfterMerge);
749
743
 
750
- const currentAuthorLix2 = await lix1.db
751
- .selectFrom("active_account")
752
- .selectAll()
753
- .executeTakeFirstOrThrow();
754
744
  await createComment({
755
745
  lix: lix2,
756
746
  parentComment: commentsLix2AfterMerge[0]!,
757
747
  content: "wrote in lix 2",
758
- createdBy: { id: currentAuthorLix2.id },
759
748
  });
760
749
  await createComment({
761
750
  lix: lix1,
762
751
  parentComment: commentsLix2AfterMerge[0]!,
763
752
  content: "wrote in lix 1",
764
- createdBy: { id: currentAuthorLix1.id },
765
753
  });
766
754
 
767
755
  const commentsLix1OnSecondMerge = await lix1.db
@@ -816,7 +804,7 @@ test.skip("it should copy change sets and merge memberships", async () => {
816
804
  });
817
805
 
818
806
  const sourceLix = await openLixInMemory({
819
- blob: await targetLix.toBlob(),
807
+ blob: await toBlob({ lix: targetLix }),
820
808
  });
821
809
 
822
810
  // expand the change set to contain another change
package/src/lix/merge.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { Lix } from "./open-lix.js";
2
2
  import { getLeafChangesOnlyInSource } from "./merge.get-leaf-changes-only-in-source.js";
3
- import { withSkipChangeQueue } from "../change-queue/with-skip-change-queue.js";
3
+ import { withSkipFileQueue } from "../file-queue/with-skip-file-queue.js";
4
4
  import type { DetectedConflict } from "../plugin/lix-plugin.js";
5
5
 
6
6
  /**
@@ -45,7 +45,7 @@ export async function merge(args: {
45
45
 
46
46
  [];
47
47
 
48
- const changesPerFile: Record<string, ArrayBuffer> = {};
48
+ const changesPerFile: Record<string, Uint8Array> = {};
49
49
 
50
50
  const fileIds = new Set(sourceChangesWithSnapshot.map((c) => c.file_id));
51
51
 
@@ -83,7 +83,7 @@ export async function merge(args: {
83
83
  metadata: file.metadata,
84
84
  };
85
85
 
86
- await withSkipChangeQueue(args.targetLix.db, async (trx) => {
86
+ await withSkipFileQueue(args.targetLix.db, async (trx) => {
87
87
  await trx
88
88
  .insertInto("file")
89
89
  .values({ ...fileToInsert })
@@ -183,7 +183,7 @@ export async function merge(args: {
183
183
 
184
184
  for (const [fileId, fileData] of Object.entries(changesPerFile)) {
185
185
  // update the file data with the applied changes
186
- await withSkipChangeQueue(trx, async (trx) => {
186
+ await withSkipFileQueue(trx, async (trx) => {
187
187
  await trx
188
188
  .updateTable("file")
189
189
  .set("data", fileData)
@@ -3,6 +3,7 @@ import {
3
3
  contentFromDatabase,
4
4
  } from "sqlite-wasm-kysely";
5
5
  import { initDb } from "../database/init-db.js";
6
+ import { closeLix } from "./close-lix.js";
6
7
 
7
8
  /**
8
9
  * Creates a new lix file.
@@ -23,8 +24,6 @@ export async function newLixFile(): Promise<Blob> {
23
24
  } catch (e) {
24
25
  throw new Error(`Failed to create new Lix file: ${e}`, { cause: e });
25
26
  } finally {
26
- // in any case destroy the memory db
27
- sqlite.close();
28
- await db.destroy();
27
+ closeLix({ lix: { db } });
29
28
  }
30
29
  }
@@ -1,5 +1,6 @@
1
1
  import { test, expect } from "vitest";
2
2
  import { openLixInMemory } from "./open-lix-in-memory.js";
3
+ import { toBlob } from "./to-blob.js";
3
4
 
4
5
  test("it should open a lix in memory", async () => {
5
6
  const lix = await openLixInMemory({});
@@ -10,6 +11,7 @@ test("it should open a lix in memory", async () => {
10
11
 
11
12
  test("it should open a lix in memory from a blob", async () => {
12
13
  const lix1 = await openLixInMemory({});
14
+
13
15
  await lix1.db
14
16
  .insertInto("file")
15
17
  .values({
@@ -18,8 +20,10 @@ test("it should open a lix in memory from a blob", async () => {
18
20
  data: new TextEncoder().encode("hello"),
19
21
  })
20
22
  .execute();
21
- const lix2 = await openLixInMemory({ blob: await lix1.toBlob() });
23
+
24
+ const lix2 = await openLixInMemory({ blob: await toBlob({ lix: lix1 }) });
22
25
  const files = await lix2.db.selectFrom("file").selectAll().execute();
26
+
23
27
  expect(files).toEqual([
24
28
  expect.objectContaining({
25
29
  id: "1",
@@ -2,6 +2,7 @@ import { expect, test } from "vitest";
2
2
  import { openLixInMemory } from "./open-lix-in-memory.js";
3
3
  import { newLixFile } from "./new-lix.js";
4
4
  import type { LixPlugin } from "../plugin/lix-plugin.js";
5
+ import { toBlob } from "./to-blob.js";
5
6
 
6
7
  test("providing plugins should be possible", async () => {
7
8
  const mockPlugin: LixPlugin = {
@@ -17,17 +18,28 @@ test("providing plugins should be possible", async () => {
17
18
  test("providing key values should be possible", async () => {
18
19
  const lix = await openLixInMemory({
19
20
  blob: await newLixFile(),
20
- keyValues: [{ key: "key", value: "value" }],
21
+ keyValues: [{ key: "mock_key", value: "value" }],
21
22
  });
22
- const value = await lix.db.selectFrom("key_value").selectAll().execute();
23
- expect(value).toContainEqual({ key: "key", value: "value" });
23
+
24
+ const value = await lix.db
25
+ .selectFrom("key_value")
26
+ .selectAll()
27
+ .where("key", "=", "mock_key")
28
+ .executeTakeFirstOrThrow();
29
+
30
+ expect(value).toMatchObject({ key: "mock_key", value: "value" });
24
31
 
25
32
  // testing overwriting key values
26
33
  const lix1 = await openLixInMemory({
27
- blob: await lix.toBlob(),
28
- keyValues: [{ key: "key", value: "value2" }],
34
+ blob: await toBlob({ lix }),
35
+ keyValues: [{ key: "mock_key", value: "value2" }],
29
36
  });
30
37
 
31
- const value1 = await lix1.db.selectFrom("key_value").selectAll().execute();
32
- expect(value1).toContainEqual({ key: "key", value: "value2" });
38
+ const value1 = await lix1.db
39
+ .selectFrom("key_value")
40
+ .selectAll()
41
+ .where("key", "=", "mock_key")
42
+
43
+ .executeTakeFirstOrThrow();
44
+ expect(value1).toMatchObject({ key: "mock_key", value: "value2" });
33
45
  });
@@ -1,13 +1,12 @@
1
1
  import type { LixPlugin } from "../plugin/lix-plugin.js";
2
2
  import { loadPlugins } from "../plugin/load-plugin.js";
3
- import { contentFromDatabase, type SqliteDatabase } from "sqlite-wasm-kysely";
3
+ import { type SqliteDatabase } from "sqlite-wasm-kysely";
4
4
  import { initDb } from "../database/init-db.js";
5
- import { initChangeQueue } from "../change-queue/init-change-queue.js";
6
- import { changeQueueSettled } from "../change-queue/change-queue-settled.js";
5
+ import { initFileQueueProcess } from "../file-queue/file-queue-process.js";
7
6
  import type { Kysely } from "kysely";
8
7
  import type { LixDatabaseSchema } from "../database/schema.js";
9
8
  import { initSyncProcess } from "../sync/sync-process.js";
10
- import type { KeyValue } from "../key-value/database-schema.js";
9
+ import type { NewKeyValue } from "../key-value/database-schema.js";
11
10
 
12
11
  export type Lix = {
13
12
  /**
@@ -22,11 +21,9 @@ export type Lix = {
22
21
  */
23
22
  sqlite: SqliteDatabase;
24
23
  db: Kysely<LixDatabaseSchema>;
25
- toBlob: () => Promise<Blob>;
26
24
  plugin: {
27
25
  getAll: () => Promise<LixPlugin[]>;
28
26
  };
29
- close: () => Promise<void>;
30
27
  };
31
28
 
32
29
  /**
@@ -52,9 +49,9 @@ export async function openLix(args: {
52
49
  * Set the key values when opening the lix.
53
50
  *
54
51
  * @example
55
- * const lix = await openLix({ keyValues: [{ key: "#lix_sync", value: "false" }] })
52
+ * const lix = await openLix({ keyValues: [{ key: "lix_sync", value: "false" }] })
56
53
  */
57
- keyValues?: KeyValue[];
54
+ keyValues?: NewKeyValue[];
58
55
  }): Promise<Lix> {
59
56
  const db = initDb({ sqlite: args.database });
60
57
 
@@ -77,27 +74,13 @@ export async function openLix(args: {
77
74
  getAll: async () => plugins,
78
75
  };
79
76
 
80
- const toBlob = async () => {
81
- await changeQueueSettled({ lix: { db } });
82
- return new Blob([contentFromDatabase(args.database)]);
83
- };
84
-
85
- initChangeQueue({
86
- lix: { db, plugin, sqlite: args.database },
87
- rawDatabase: args.database,
88
- });
77
+ initFileQueueProcess({ lix: { db, plugin, sqlite: args.database } });
89
78
 
90
- initSyncProcess({ lix: { db, plugin, toBlob } });
79
+ initSyncProcess({ lix: { db, plugin, sqlite: args.database } });
91
80
 
92
81
  return {
93
82
  db,
94
83
  sqlite: args.database,
95
- toBlob,
96
84
  plugin,
97
- close: async () => {
98
- await changeQueueSettled({ lix: { db } });
99
- // args.database.close();
100
- // await db.destroy();
101
- },
102
85
  };
103
86
  }
@@ -0,0 +1,14 @@
1
+ import { contentFromDatabase } from "sqlite-wasm-kysely";
2
+ import type { Lix } from "./open-lix.js";
3
+
4
+ /**
5
+ * Convert the lix to a blob.
6
+ *
7
+ * @example
8
+ * const blob = await toBlob({ lix })
9
+ */
10
+ export async function toBlob(args: {
11
+ lix: Pick<Lix, "db" | "sqlite">;
12
+ }): Promise<Blob> {
13
+ return new Blob([contentFromDatabase(args.lix.sqlite)]);
14
+ }