@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,5 +1,8 @@
1
+ import { fileQueueSettled } from "../../file-queue/file-queue-settled.js";
2
+ import { closeLix } from "../../lix/close-lix.js";
1
3
  import { openLixInMemory } from "../../lix/open-lix-in-memory.js";
2
4
  import type { Lix } from "../../lix/open-lix.js";
5
+ import { toBlob } from "../../lix/to-blob.js";
3
6
  import type { LsaEnvironment } from "./environment.js";
4
7
 
5
8
  /**
@@ -72,7 +75,7 @@ export const createLsaInMemoryEnvironment = (): LsaEnvironment => {
72
75
  lix = await openLixInMemory({
73
76
  blob,
74
77
  // don't sync the server with itself
75
- keyValues: [{ key: "#lix_sync", value: "false" }],
78
+ keyValues: [{ key: "lix_sync", value: "false" }],
76
79
  });
77
80
 
78
81
  lix.sqlite.exec("PRAGMA foreign_keys = OFF;");
@@ -100,8 +103,9 @@ export const createLsaInMemoryEnvironment = (): LsaEnvironment => {
100
103
  if (connections.size === 0) {
101
104
  // TODO no concurrency guarantees
102
105
  const lix = openLixes.get(args.id);
103
- const blob = await lix!.toBlob();
104
- await lix?.close();
106
+ await fileQueueSettled({ lix: lix! });
107
+ const blob = await toBlob({ lix: lix! });
108
+ await closeLix({ lix: lix! });
105
109
  openConnections.delete(args.id);
106
110
  openLixes.delete(args.id);
107
111
  store.set(args.id, blob);
@@ -3,6 +3,7 @@ import { createServerApiHandler } from "../create-server-api-handler.js";
3
3
  import { newLixFile } from "../../lix/new-lix.js";
4
4
  import { openLixInMemory } from "../../lix/open-lix-in-memory.js";
5
5
  import { createLsaInMemoryEnvironment } from "../environment/create-in-memory-environment.js";
6
+ import { toBlob } from "../../lix/to-blob.js";
6
7
 
7
8
  test("it should fetch the lix file from the server", async () => {
8
9
  const lix = await openLixInMemory({
@@ -26,7 +27,7 @@ test("it should fetch the lix file from the server", async () => {
26
27
  await lsaHandler(
27
28
  new Request("http://localhost:3000/lsa/new-v1", {
28
29
  method: "POST",
29
- body: await lix.toBlob(),
30
+ body: await toBlob({ lix }),
30
31
  })
31
32
  );
32
33
 
@@ -103,20 +104,20 @@ test("it should return 400 for a request without lix_id", async () => {
103
104
  expect(responseJson.error).toBe("Missing required field 'lix_id'");
104
105
  });
105
106
 
106
- test("#lix_sync is set to true", async () => {
107
+ test("lix_sync is set to true", async () => {
107
108
  const environment = createLsaInMemoryEnvironment();
108
109
  const lsaHandler = await createServerApiHandler({ environment });
109
110
 
110
111
  const lix = await openLixInMemory({
111
112
  blob: await newLixFile(),
112
- keyValues: [{ key: "#lix_sync", value: "false" }],
113
+ keyValues: [{ key: "lix_sync", value: "false" }],
113
114
  });
114
115
 
115
116
  // Store the lix file
116
117
  const response0 = await lsaHandler(
117
118
  new Request("http://localhost:3000/lsa/new-v1", {
118
119
  method: "POST",
119
- body: await lix.toBlob(),
120
+ body: await toBlob({ lix }),
120
121
  })
121
122
  );
122
123
 
@@ -138,7 +139,7 @@ test("#lix_sync is set to true", async () => {
138
139
 
139
140
  const lixSync = await lixFromServer.db
140
141
  .selectFrom("key_value")
141
- .where("key", "=", "#lix_sync")
142
+ .where("key", "=", "lix_sync")
142
143
  .selectAll()
143
144
  .executeTakeFirstOrThrow();
144
145
 
@@ -47,12 +47,10 @@ export const route: LixServerApiHandlerRoute = async (context) => {
47
47
  content: new Uint8Array(await blob!.arrayBuffer()),
48
48
  });
49
49
 
50
- sqlite.exec("UPDATE key_value SET value = 'true' WHERE key = '#lix_sync'");
50
+ sqlite.exec("UPDATE key_value SET value = 'true' WHERE key = 'lix_sync'");
51
51
 
52
52
  const blob2 = new Blob([contentFromDatabase(sqlite)]);
53
53
 
54
- sqlite.close();
55
-
56
54
  return new Response(blob2, {
57
55
  status: 200,
58
56
  headers: {
@@ -3,6 +3,7 @@ import { createServerApiHandler } from "../create-server-api-handler.js";
3
3
  import { newLixFile } from "../../lix/new-lix.js";
4
4
  import { openLixInMemory } from "../../lix/open-lix-in-memory.js";
5
5
  import { createLsaInMemoryEnvironment } from "../environment/create-in-memory-environment.js";
6
+ import { toBlob } from "../../lix/to-blob.js";
6
7
 
7
8
  test("it should store the lix file", async () => {
8
9
  const initLix = await openLixInMemory({
@@ -22,7 +23,7 @@ test("it should store the lix file", async () => {
22
23
  const response = await lsaHandler(
23
24
  new Request("http://localhost:3000/lsa/new-v1", {
24
25
  method: "POST",
25
- body: await initLix.toBlob(),
26
+ body: await toBlob({ lix: initLix }),
26
27
  })
27
28
  );
28
29
  const json = await response.json();
@@ -11,7 +11,9 @@ export const route: LixServerApiHandlerRoute = async (context) => {
11
11
  lix = await openLixInMemory({
12
12
  blob,
13
13
  // turn off sync for server
14
- keyValues: [{ key: "#lix_sync", value: "false" }],
14
+ keyValues: [
15
+ { key: "lix_sync", value: "false", skip_change_control: true },
16
+ ],
15
17
  });
16
18
  } catch {
17
19
  return new Response(null, {
@@ -5,6 +5,7 @@ import { createServerApiHandler } from "../create-server-api-handler.js";
5
5
  import { mockJsonSnapshot } from "../../snapshot/mock-json-snapshot.js";
6
6
  import { mockChange } from "../../change/mock-change.js";
7
7
  import { createLsaInMemoryEnvironment } from "../environment/create-in-memory-environment.js";
8
+ import { toBlob } from "../../lix/to-blob.js";
8
9
 
9
10
  type RequestBody =
10
11
  LixServerApi.paths["/lsa/pull-v1"]["post"]["requestBody"]["content"]["application/json"];
@@ -27,7 +28,7 @@ test("it should pull rows successfully", async () => {
27
28
 
28
29
  const environment = createLsaInMemoryEnvironment();
29
30
 
30
- await environment.setLix({ id: id.value, blob: await lix.toBlob() });
31
+ await environment.setLix({ id: id.value, blob: await toBlob({ lix }) });
31
32
 
32
33
  const lsaHandler = await createServerApiHandler({ environment });
33
34
 
@@ -79,7 +80,7 @@ test("it should specifically be able to handle snapshots which use json binary a
79
80
  .execute();
80
81
 
81
82
  const environment = createLsaInMemoryEnvironment();
82
- await environment.setLix({ id, blob: await lix.toBlob() });
83
+ await environment.setLix({ id, blob: await toBlob({ lix }) });
83
84
 
84
85
  const lsa = await createServerApiHandler({ environment });
85
86
 
@@ -172,7 +173,7 @@ test("it should handle empty tables gracefully", async () => {
172
173
  .executeTakeFirstOrThrow();
173
174
 
174
175
  const environment = createLsaInMemoryEnvironment();
175
- await environment.setLix({ id, blob: await lix.toBlob() });
176
+ await environment.setLix({ id, blob: await toBlob({ lix }) });
176
177
 
177
178
  const lsa = await createServerApiHandler({ environment });
178
179
 
@@ -9,6 +9,7 @@ import { createVersion } from "../../version/create-version.js";
9
9
  import { switchVersion } from "../../version/switch-version.js";
10
10
  import { pullFromServer } from "../../sync/pull-from-server.js";
11
11
  import { createLsaInMemoryEnvironment } from "../environment/create-in-memory-environment.js";
12
+ import { toBlob } from "../../lix/to-blob.js";
12
13
 
13
14
  test("it should push data successfully", async () => {
14
15
  const lix = await openLixInMemory({});
@@ -19,7 +20,7 @@ test("it should push data successfully", async () => {
19
20
  .executeTakeFirstOrThrow();
20
21
 
21
22
  const environment = createLsaInMemoryEnvironment();
22
- await environment.setLix({ id, blob: await lix.toBlob() });
23
+ await environment.setLix({ id, blob: await toBlob({ lix }) });
23
24
 
24
25
  const lsaHandler = await createServerApiHandler({ environment });
25
26
 
@@ -130,7 +131,7 @@ test("it should return 400 for a failed insert operation", async () => {
130
131
 
131
132
  const environment = createLsaInMemoryEnvironment();
132
133
 
133
- environment.setLix({ id, blob: await lix.toBlob() });
134
+ environment.setLix({ id, blob: await toBlob({ lix }) });
134
135
 
135
136
  const lsa = await createServerApiHandler({ environment });
136
137
 
@@ -169,7 +170,7 @@ test.skip("it should detect conflicts", async () => {
169
170
 
170
171
  // initialize client
171
172
  const lixOnClient = await openLixInMemory({
172
- blob: await lixOnServer.toBlob(),
173
+ blob: await toBlob({ lix: lixOnServer }),
173
174
  });
174
175
 
175
176
  const lixId = await lixOnServer.db
@@ -192,7 +193,7 @@ test.skip("it should detect conflicts", async () => {
192
193
 
193
194
  await environment.setLix({
194
195
  id: lixId.value,
195
- blob: await lixOnServer.toBlob(),
196
+ blob: await toBlob({ lix: lixOnServer }),
196
197
  });
197
198
 
198
199
  // client has/creates value1 for mock_key
@@ -4,11 +4,14 @@ import { openLixInMemory } from "../lix/open-lix-in-memory.js";
4
4
  import { pullFromServer } from "./pull-from-server.js";
5
5
  import { mockJsonSnapshot } from "../snapshot/mock-json-snapshot.js";
6
6
  import { createLsaInMemoryEnvironment } from "../server-api-handler/environment/create-in-memory-environment.js";
7
+ import { toBlob } from "../lix/to-blob.js";
7
8
 
8
9
  test("pull rows of multiple tables from server successfully and applies them", async () => {
9
10
  const lixOnServer = await openLixInMemory({});
10
11
 
11
- const lix = await openLixInMemory({ blob: await lixOnServer.toBlob() });
12
+ const lix = await openLixInMemory({
13
+ blob: await toBlob({ lix: lixOnServer }),
14
+ });
12
15
 
13
16
  const { value: id } = await lixOnServer.db
14
17
  .selectFrom("key_value")
@@ -38,7 +41,7 @@ test("pull rows of multiple tables from server successfully and applies them", a
38
41
  await lsaHandler(
39
42
  new Request("http://localhost:3000/lsa/new-v1", {
40
43
  method: "POST",
41
- body: await lixOnServer.toBlob(),
44
+ body: await toBlob({ lix: lixOnServer }),
42
45
  headers: {
43
46
  "Content-Type": "application/json",
44
47
  },
@@ -66,13 +69,15 @@ test("pull rows of multiple tables from server successfully and applies them", a
66
69
  .executeTakeFirstOrThrow();
67
70
 
68
71
  expect(account).toEqual({ id: "account0", name: "test account" });
69
- expect(mockKey).toEqual({ key: "mock-key", value: "mock-value" });
72
+ expect(mockKey).toMatchObject({ key: "mock-key", value: "mock-value" });
70
73
  });
71
74
 
72
75
  test("it handles snapshot.content being json binary", async () => {
73
76
  const lixOnServer = await openLixInMemory({});
74
77
 
75
- const lix = await openLixInMemory({ blob: await lixOnServer.toBlob() });
78
+ const lix = await openLixInMemory({
79
+ blob: await toBlob({ lix: lixOnServer }),
80
+ });
76
81
 
77
82
  const { value: id } = await lixOnServer.db
78
83
  .selectFrom("key_value")
@@ -101,7 +106,7 @@ test("it handles snapshot.content being json binary", async () => {
101
106
  await lsaHandler(
102
107
  new Request("http://localhost:3000/lsa/new-v1", {
103
108
  method: "POST",
104
- body: await lixOnServer.toBlob(),
109
+ body: await toBlob({ lix: lixOnServer }),
105
110
  headers: {
106
111
  "Content-Type": "application/json",
107
112
  },
@@ -141,7 +146,9 @@ test("rows changed on the client more recently should not be updated", async ()
141
146
  })
142
147
  .executeTakeFirstOrThrow();
143
148
 
144
- const lix = await openLixInMemory({ blob: await lixOnServer.toBlob() });
149
+ const lix = await openLixInMemory({
150
+ blob: await toBlob({ lix: lixOnServer }),
151
+ });
145
152
 
146
153
  const environment = createLsaInMemoryEnvironment();
147
154
  const lsaHandler = await createServerApiHandler({ environment });
@@ -152,7 +159,7 @@ test("rows changed on the client more recently should not be updated", async ()
152
159
  await lsaHandler(
153
160
  new Request("http://localhost:3000/lsa/new-v1", {
154
161
  method: "POST",
155
- body: await lixOnServer.toBlob(),
162
+ body: await toBlob({ lix: lixOnServer }),
156
163
  headers: {
157
164
  "Content-Type": "application/json",
158
165
  },
@@ -179,7 +186,10 @@ test("rows changed on the client more recently should not be updated", async ()
179
186
  .selectAll()
180
187
  .executeTakeFirstOrThrow();
181
188
 
182
- expect(mockKey).toEqual({ key: "mock-key", value: "mock-value-updated" });
189
+ expect(mockKey).toMatchObject({
190
+ key: "mock-key",
191
+ value: "mock-value-updated",
192
+ });
183
193
  });
184
194
 
185
195
  // the change table now models "change control". no more last edit wins needed
@@ -192,7 +202,9 @@ test.skip("rows changed on the server more recently should be updated on the cli
192
202
 
193
203
  // create a lix and clone it for the client - so they share the same lix id
194
204
  const remoteLix = await openLixInMemory({});
195
- const localLix = await openLixInMemory({ blob: await remoteLix.toBlob() });
205
+ const localLix = await openLixInMemory({
206
+ blob: await toBlob({ lix: remoteLix }),
207
+ });
196
208
 
197
209
  // insert mock data into server lix
198
210
  await remoteLix.db
@@ -234,7 +246,7 @@ test.skip("rows changed on the server more recently should be updated on the cli
234
246
  await lsaHandler(
235
247
  new Request("http://localhost:3000/lsa/new-v1", {
236
248
  method: "POST",
237
- body: await remoteLix.toBlob(),
249
+ body: await toBlob({ lix: remoteLix }),
238
250
  headers: {
239
251
  "Content-Type": "application/json",
240
252
  },
@@ -347,7 +359,7 @@ test("non-conflicting changes from the server should for the same version should
347
359
 
348
360
  global.fetch = vi.fn((request) => lsaHandler(request));
349
361
 
350
- const lixOnServer = await openLixInMemory({ blob: await lix.toBlob() });
362
+ const lixOnServer = await openLixInMemory({ blob: await toBlob({ lix }) });
351
363
 
352
364
  // insert data on the server that the client does not have yet
353
365
  await lixOnServer.db
@@ -369,7 +381,10 @@ test("non-conflicting changes from the server should for the same version should
369
381
  expect.arrayContaining([
370
382
  expect.objectContaining({
371
383
  version_id: currentVersion.id,
372
- content: { key: "mock-key", value: "mock-value" },
384
+ content: expect.objectContaining({
385
+ key: "mock-key",
386
+ value: "mock-value",
387
+ }),
373
388
  }),
374
389
  ])
375
390
  );
@@ -377,7 +392,7 @@ test("non-conflicting changes from the server should for the same version should
377
392
  await lsaHandler(
378
393
  new Request("http://localhost:3000/lsa/new-v1", {
379
394
  method: "POST",
380
- body: await lixOnServer.toBlob(),
395
+ body: await toBlob({ lix: lixOnServer }),
381
396
  headers: {
382
397
  "Content-Type": "application/json",
383
398
  },
@@ -405,6 +420,6 @@ test("non-conflicting changes from the server should for the same version should
405
420
  .select("snapshot.content as content")
406
421
  .execute();
407
422
 
408
- expect(mockKey).toEqual({ key: "mock-key", value: "mock-value" });
423
+ expect(mockKey).toMatchObject({ key: "mock-key", value: "mock-value" });
409
424
  expect(versionChanges).toEqual(expect.arrayContaining(serverVersionChanges));
410
425
  });
@@ -133,8 +133,6 @@ export async function pullFromServer(args: {
133
133
  });
134
134
 
135
135
  if (changesToApply.length > 0) {
136
- // the changes already exists hence prevent own change control
137
- // from creating new changes for the applied changes
138
136
  await applyChanges({
139
137
  lix: { ...args.lix, db: trx },
140
138
  changes: changesToApply,
@@ -5,10 +5,11 @@ import { pushToServer } from "./push-to-server.js";
5
5
  import type { LixFile } from "../database/schema.js";
6
6
  import type { Account } from "../account/database-schema.js";
7
7
  import { newLixFile } from "../lix/new-lix.js";
8
- import type { KeyValue } from "../key-value/database-schema.js";
8
+ import type { NewKeyValue } from "../key-value/database-schema.js";
9
9
  import { mockJsonSnapshot } from "../snapshot/mock-json-snapshot.js";
10
10
  import { pullFromServer } from "./pull-from-server.js";
11
11
  import { createLsaInMemoryEnvironment } from "../server-api-handler/environment/create-in-memory-environment.js";
12
+ import { toBlob } from "../lix/to-blob.js";
12
13
 
13
14
  test("push rows of multiple tables to server successfully", async () => {
14
15
  const lixBlob = await newLixFile();
@@ -30,7 +31,7 @@ test("push rows of multiple tables to server successfully", async () => {
30
31
  await lsaHandler(
31
32
  new Request("http://localhost:3000/lsa/new-v1", {
32
33
  method: "POST",
33
- body: await lix.toBlob(),
34
+ body: await toBlob({ lix }),
34
35
  })
35
36
  );
36
37
 
@@ -83,11 +84,11 @@ test("push rows of multiple tables to server successfully", async () => {
83
84
  { id: "account0", name: "some account" } satisfies Account,
84
85
  ]);
85
86
  expect(keyValueChangesOnServer.map((c) => c.content)).toEqual([
86
- {
87
+ expect.objectContaining({
87
88
  key: "mock-key",
88
89
  value: "mock-value",
89
- },
90
- ] satisfies KeyValue[]);
90
+ }),
91
+ ] satisfies NewKeyValue[]);
91
92
  });
92
93
 
93
94
  test("push-pull-push with two clients", async () => {
@@ -111,7 +112,7 @@ test("push-pull-push with two clients", async () => {
111
112
  await lsaHandler(
112
113
  new Request("http://localhost:3000/lsa/new-v1", {
113
114
  method: "POST",
114
- body: await client1.toBlob(),
115
+ body: await toBlob({ lix: client1 }),
115
116
  })
116
117
  );
117
118
 
@@ -165,10 +166,10 @@ test("push-pull-push with two clients", async () => {
165
166
 
166
167
  expect(client2KeyValueAfterPull).toEqual(
167
168
  expect.arrayContaining([
168
- {
169
+ expect.objectContaining({
169
170
  key: "mock-key",
170
171
  value: "mock-value from client 1",
171
- } satisfies KeyValue,
172
+ } satisfies NewKeyValue),
172
173
  ])
173
174
  );
174
175
 
@@ -260,15 +261,18 @@ test("push-pull-push with two clients", async () => {
260
261
 
261
262
  expect(keyValueChangesOnServer.map((c) => c.content)).toEqual(
262
263
  expect.arrayContaining([
263
- {
264
+ expect.objectContaining({
264
265
  key: "mock-key",
265
266
  value: "mock-value from client 1",
266
- },
267
- {
267
+ }),
268
+ expect.objectContaining({
268
269
  key: "mock-key",
269
270
  value: "mock-value from client 1 - updated by client 2",
270
- },
271
- { key: "mock-key-2", value: "mock-value from client 2" },
271
+ }),
272
+ expect.objectContaining({
273
+ key: "mock-key-2",
274
+ value: "mock-value from client 2",
275
+ }),
272
276
  ])
273
277
  );
274
278
  });
@@ -291,7 +295,7 @@ test("it should handle snapshots.content json binaries", async () => {
291
295
  await lsaHandler(
292
296
  new Request("http://localhost:3000/lsa/new-v1", {
293
297
  method: "POST",
294
- body: await lix.toBlob(),
298
+ body: await toBlob({ lix }),
295
299
  })
296
300
  );
297
301
 
@@ -345,7 +349,7 @@ test.todo("it should handle binary values", async () => {
345
349
  await lsaHandler(
346
350
  new Request("http://localhost:3000/lsa/new", {
347
351
  method: "POST",
348
- body: await lix.toBlob(),
352
+ body: await toBlob({ lix }),
349
353
  })
350
354
  );
351
355
 
@@ -8,6 +8,7 @@ import { createVersion } from "../version/create-version.js";
8
8
  import { switchVersion } from "../version/switch-version.js";
9
9
  import type { Version } from "../database/schema.js";
10
10
  import { executeSync } from "../database/execute-sync.js";
11
+ import { toBlob } from "../lix/to-blob.js";
11
12
 
12
13
  test("versions should be synced", async () => {
13
14
  const environment = createLsaInMemoryEnvironment();
@@ -16,7 +17,7 @@ test("versions should be synced", async () => {
16
17
  global.fetch = vi.fn((request) => lsaHandler(request));
17
18
 
18
19
  const lix0 = await openLixInMemory({
19
- keyValues: [{ key: "#lix_sync", value: "true" }],
20
+ keyValues: [{ key: "lix_server_url", value: "http://mock.com" }],
20
21
  });
21
22
 
22
23
  // @ts-expect-error - eases debugging
@@ -32,32 +33,26 @@ test("versions should be synced", async () => {
32
33
  await lsaHandler(
33
34
  new Request("http://mock.com/lsa/new-v1", {
34
35
  method: "POST",
35
- body: await lix0.toBlob(),
36
+ body: await toBlob({ lix: lix0 }),
36
37
  })
37
38
  );
38
39
 
39
40
  // create a second client
40
41
  const lix1 = await openLixInMemory({
41
- blob: await lix0.toBlob(),
42
- keyValues: [{ key: "#lix_sync", value: "true" }],
42
+ blob: await toBlob({ lix: lix0 }),
43
+ keyValues: [{ key: "lix_sync", value: "true" }],
43
44
  });
44
45
 
45
46
  // start syncing
46
- await lix0.db
47
- .insertInto("key_value")
48
- .values({
49
- key: "lix_server_url",
50
- value: "http://mock.com",
51
- })
52
- .execute();
53
-
54
- await lix1.db
55
- .insertInto("key_value")
56
- .values({
57
- key: "lix_server_url",
58
- value: "http://mock.com",
59
- })
60
- .execute();
47
+ await Promise.all(
48
+ [lix0, lix1].map((lix) =>
49
+ lix.db
50
+ .updateTable("key_value")
51
+ .where("key", "=", "lix_sync")
52
+ .set({ value: "true" })
53
+ .execute()
54
+ )
55
+ );
61
56
 
62
57
  // @ts-expect-error - eases debugging
63
58
  lix1.db.__name = "lix1";
@@ -74,7 +69,7 @@ test("versions should be synced", async () => {
74
69
  .executeTakeFirstOrThrow();
75
70
  version0 = await createVersion({
76
71
  lix: { ...lix0, db: trx },
77
- parent: currentVersion,
72
+ from: currentVersion,
78
73
  name: "version0",
79
74
  });
80
75
  await switchVersion({ lix: { ...lix0, db: trx }, to: version0 });
@@ -113,17 +108,16 @@ test("versions should be synced", async () => {
113
108
  expect(lix0Versions).toEqual(lix1Versions);
114
109
 
115
110
  // expecting both lix0 and lix1 to have the same version changes
116
- const lix0VersionChanges = await lix0.db
117
- .selectFrom("version_change")
118
- .orderBy("change_id", "desc")
119
- .selectAll()
120
- .execute();
121
-
122
- const lix1VersionChanges = await lix1.db
123
- .selectFrom("version_change")
124
- .orderBy("change_id", "desc")
125
- .selectAll()
126
- .execute();
111
+ const [lix0VersionChanges, lix1VersionChanges] = await Promise.all(
112
+ [lix0, lix1].map((lix) =>
113
+ lix.db
114
+ .selectFrom("version_change")
115
+ .orderBy("change_id", "desc")
116
+ .orderBy("version_id", "desc")
117
+ .selectAll()
118
+ .execute()
119
+ )
120
+ );
127
121
 
128
122
  expect(lix0VersionChanges).toEqual(lix1VersionChanges);
129
123
  });
@@ -137,7 +131,7 @@ test("switching synced versions should work", async () => {
137
131
  global.executeSync = executeSync;
138
132
 
139
133
  const lix0 = await openLixInMemory({
140
- keyValues: [{ key: "#lix_sync", value: "true" }],
134
+ keyValues: [{ key: "lix_sync", value: "true" }],
141
135
  });
142
136
  // @ts-expect-error - eases debugging
143
137
  lix0.db.__name = "lix0";
@@ -154,7 +148,7 @@ test("switching synced versions should work", async () => {
154
148
  await lsaHandler(
155
149
  new Request("http://mock.com/lsa/new-v1", {
156
150
  method: "POST",
157
- body: await lix0.toBlob(),
151
+ body: await toBlob({ lix: lix0 }),
158
152
  })
159
153
  );
160
154
 
@@ -169,8 +163,8 @@ test("switching synced versions should work", async () => {
169
163
 
170
164
  // create a second client
171
165
  const lix1 = await openLixInMemory({
172
- blob: await lix0.toBlob(),
173
- keyValues: [{ key: "#lix_sync", value: "true" }],
166
+ blob: await toBlob({ lix: lix0 }),
167
+ keyValues: [{ key: "lix_sync", value: "true" }],
174
168
  });
175
169
 
176
170
  // @ts-expect-error - eases debugging
@@ -187,7 +181,7 @@ test("switching synced versions should work", async () => {
187
181
  const version0 = await createVersion({
188
182
  lix: lix0,
189
183
  name: "version0",
190
- parent: currentVersion,
184
+ from: currentVersion,
191
185
  });
192
186
 
193
187
  await switchVersion({ lix: lix0, to: version0 });
@@ -239,13 +233,13 @@ test("switching synced versions should work", async () => {
239
233
  .selectAll()
240
234
  .executeTakeFirst();
241
235
 
242
- expect(keyValue).toEqual({
236
+ expect(keyValue).toMatchObject({
243
237
  key: "mock-key",
244
238
  value: "mock",
245
239
  });
246
240
  });
247
241
 
248
- test("doesnt sync if #lix_sync is not true", async () => {
242
+ test("doesnt sync if lix_sync is not true", async () => {
249
243
  const environment = createLsaInMemoryEnvironment();
250
244
  const lsaHandler = await createServerApiHandler({ environment });
251
245
  global.fetch = vi.fn((request) => lsaHandler(request));
@@ -262,14 +256,14 @@ test("doesnt sync if #lix_sync is not true", async () => {
262
256
  await lsaHandler(
263
257
  new Request("http://mock.com/lsa/new-v1", {
264
258
  method: "POST",
265
- body: await lix.toBlob(),
259
+ body: await toBlob({ lix }),
266
260
  })
267
261
  );
268
262
 
269
263
  await lix.db
270
264
  .updateTable("key_value")
271
265
  .set({ value: "false" })
272
- .where("key", "=", "#lix_sync")
266
+ .where("key", "=", "lix_sync")
273
267
  .execute();
274
268
 
275
269
  await lix.db
@@ -301,7 +295,7 @@ test("doesnt sync if #lix_sync is not true", async () => {
301
295
  await lix.db
302
296
  .updateTable("key_value")
303
297
  .set({ value: "true" })
304
- .where("key", "=", "#lix_sync")
298
+ .where("key", "=", "lix_sync")
305
299
  .execute();
306
300
 
307
301
  await new Promise((resolve) => setTimeout(resolve, 1010));
@@ -317,10 +311,10 @@ test("doesnt sync if #lix_sync is not true", async () => {
317
311
  expect(keyValueChangesOnServerAfterSync).toEqual(
318
312
  expect.arrayContaining([
319
313
  expect.objectContaining({
320
- content: {
314
+ content: expect.objectContaining({
321
315
  key: "foo",
322
316
  value: "bar",
323
- },
317
+ }),
324
318
  }),
325
319
  ])
326
320
  );