@livestore/common 0.3.0-dev.3 → 0.3.0-dev.31

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 (426) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/__tests__/fixture.d.ts +83 -221
  3. package/dist/__tests__/fixture.d.ts.map +1 -1
  4. package/dist/__tests__/fixture.js +33 -11
  5. package/dist/__tests__/fixture.js.map +1 -1
  6. package/dist/adapter-types.d.ts +128 -68
  7. package/dist/adapter-types.d.ts.map +1 -1
  8. package/dist/adapter-types.js +36 -7
  9. package/dist/adapter-types.js.map +1 -1
  10. package/dist/bounded-collections.d.ts.map +1 -1
  11. package/dist/debug-info.d.ts +1 -1
  12. package/dist/debug-info.d.ts.map +1 -1
  13. package/dist/debug-info.js +1 -0
  14. package/dist/debug-info.js.map +1 -1
  15. package/dist/devtools/devtools-messages-client-session.d.ts +389 -0
  16. package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -0
  17. package/dist/devtools/devtools-messages-client-session.js +96 -0
  18. package/dist/devtools/devtools-messages-client-session.js.map +1 -0
  19. package/dist/devtools/devtools-messages-common.d.ts +68 -0
  20. package/dist/devtools/devtools-messages-common.d.ts.map +1 -0
  21. package/dist/devtools/devtools-messages-common.js +60 -0
  22. package/dist/devtools/devtools-messages-common.js.map +1 -0
  23. package/dist/devtools/devtools-messages-leader.d.ts +394 -0
  24. package/dist/devtools/devtools-messages-leader.d.ts.map +1 -0
  25. package/dist/devtools/devtools-messages-leader.js +147 -0
  26. package/dist/devtools/devtools-messages-leader.js.map +1 -0
  27. package/dist/devtools/devtools-messages.d.ts +3 -592
  28. package/dist/devtools/devtools-messages.d.ts.map +1 -1
  29. package/dist/devtools/devtools-messages.js +3 -171
  30. package/dist/devtools/devtools-messages.js.map +1 -1
  31. package/dist/devtools/devtools-sessioninfo.d.ts +28 -0
  32. package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -0
  33. package/dist/devtools/devtools-sessioninfo.js +34 -0
  34. package/dist/devtools/devtools-sessioninfo.js.map +1 -0
  35. package/dist/devtools/mod.d.ts +39 -0
  36. package/dist/devtools/mod.d.ts.map +1 -0
  37. package/dist/devtools/mod.js +27 -0
  38. package/dist/devtools/mod.js.map +1 -0
  39. package/dist/index.d.ts +4 -11
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +4 -7
  42. package/dist/index.js.map +1 -1
  43. package/dist/leader-thread/LeaderSyncProcessor.d.ts +62 -0
  44. package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -0
  45. package/dist/leader-thread/LeaderSyncProcessor.js +589 -0
  46. package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -0
  47. package/dist/leader-thread/apply-event.d.ts +16 -0
  48. package/dist/leader-thread/apply-event.d.ts.map +1 -0
  49. package/dist/leader-thread/apply-event.js +103 -0
  50. package/dist/leader-thread/apply-event.js.map +1 -0
  51. package/dist/leader-thread/connection.d.ts +34 -6
  52. package/dist/leader-thread/connection.d.ts.map +1 -1
  53. package/dist/leader-thread/connection.js +22 -7
  54. package/dist/leader-thread/connection.js.map +1 -1
  55. package/dist/leader-thread/eventlog.d.ts +27 -0
  56. package/dist/leader-thread/eventlog.d.ts.map +1 -0
  57. package/dist/leader-thread/eventlog.js +123 -0
  58. package/dist/leader-thread/eventlog.js.map +1 -0
  59. package/dist/leader-thread/leader-worker-devtools.d.ts +1 -1
  60. package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
  61. package/dist/leader-thread/leader-worker-devtools.js +154 -132
  62. package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
  63. package/dist/leader-thread/make-leader-thread-layer.d.ts +26 -12
  64. package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
  65. package/dist/leader-thread/make-leader-thread-layer.js +82 -47
  66. package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
  67. package/dist/leader-thread/mod.d.ts +1 -1
  68. package/dist/leader-thread/mod.d.ts.map +1 -1
  69. package/dist/leader-thread/mod.js +1 -1
  70. package/dist/leader-thread/mod.js.map +1 -1
  71. package/dist/leader-thread/recreate-db.d.ts +4 -2
  72. package/dist/leader-thread/recreate-db.d.ts.map +1 -1
  73. package/dist/leader-thread/recreate-db.js +35 -25
  74. package/dist/leader-thread/recreate-db.js.map +1 -1
  75. package/dist/leader-thread/shutdown-channel.d.ts +2 -5
  76. package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
  77. package/dist/leader-thread/shutdown-channel.js +2 -4
  78. package/dist/leader-thread/shutdown-channel.js.map +1 -1
  79. package/dist/leader-thread/types.d.ts +86 -39
  80. package/dist/leader-thread/types.d.ts.map +1 -1
  81. package/dist/leader-thread/types.js +1 -3
  82. package/dist/leader-thread/types.js.map +1 -1
  83. package/dist/materializer-helper.d.ts +23 -0
  84. package/dist/materializer-helper.d.ts.map +1 -0
  85. package/dist/materializer-helper.js +70 -0
  86. package/dist/materializer-helper.js.map +1 -0
  87. package/dist/otel.d.ts +2 -0
  88. package/dist/otel.d.ts.map +1 -1
  89. package/dist/otel.js +5 -0
  90. package/dist/otel.js.map +1 -1
  91. package/dist/query-builder/api.d.ts +158 -55
  92. package/dist/query-builder/api.d.ts.map +1 -1
  93. package/dist/query-builder/api.js +3 -5
  94. package/dist/query-builder/api.js.map +1 -1
  95. package/dist/query-builder/astToSql.d.ts +7 -0
  96. package/dist/query-builder/astToSql.d.ts.map +1 -0
  97. package/dist/query-builder/astToSql.js +190 -0
  98. package/dist/query-builder/astToSql.js.map +1 -0
  99. package/dist/query-builder/impl.d.ts +3 -8
  100. package/dist/query-builder/impl.d.ts.map +1 -1
  101. package/dist/query-builder/impl.js +166 -124
  102. package/dist/query-builder/impl.js.map +1 -1
  103. package/dist/query-builder/impl.test.d.ts +86 -1
  104. package/dist/query-builder/impl.test.d.ts.map +1 -1
  105. package/dist/query-builder/impl.test.js +411 -69
  106. package/dist/query-builder/impl.test.js.map +1 -1
  107. package/dist/query-builder/mod.d.ts +7 -0
  108. package/dist/query-builder/mod.d.ts.map +1 -1
  109. package/dist/query-builder/mod.js +7 -0
  110. package/dist/query-builder/mod.js.map +1 -1
  111. package/dist/rehydrate-from-eventlog.d.ts +14 -0
  112. package/dist/rehydrate-from-eventlog.d.ts.map +1 -0
  113. package/dist/rehydrate-from-eventlog.js +65 -0
  114. package/dist/rehydrate-from-eventlog.js.map +1 -0
  115. package/dist/schema/EventDef.d.ts +136 -0
  116. package/dist/schema/EventDef.d.ts.map +1 -0
  117. package/dist/schema/EventDef.js +58 -0
  118. package/dist/schema/EventDef.js.map +1 -0
  119. package/dist/schema/EventId.d.ts +35 -15
  120. package/dist/schema/EventId.d.ts.map +1 -1
  121. package/dist/schema/EventId.js +57 -11
  122. package/dist/schema/EventId.js.map +1 -1
  123. package/dist/schema/EventId.test.d.ts +2 -0
  124. package/dist/schema/EventId.test.d.ts.map +1 -0
  125. package/dist/schema/EventId.test.js +11 -0
  126. package/dist/schema/EventId.test.js.map +1 -0
  127. package/dist/schema/LiveStoreEvent.d.ts +255 -0
  128. package/dist/schema/LiveStoreEvent.d.ts.map +1 -0
  129. package/dist/schema/LiveStoreEvent.js +118 -0
  130. package/dist/schema/LiveStoreEvent.js.map +1 -0
  131. package/dist/schema/client-document-def.d.ts +223 -0
  132. package/dist/schema/client-document-def.d.ts.map +1 -0
  133. package/dist/schema/client-document-def.js +170 -0
  134. package/dist/schema/client-document-def.js.map +1 -0
  135. package/dist/schema/client-document-def.test.d.ts +2 -0
  136. package/dist/schema/client-document-def.test.d.ts.map +1 -0
  137. package/dist/schema/client-document-def.test.js +201 -0
  138. package/dist/schema/client-document-def.test.js.map +1 -0
  139. package/dist/schema/db-schema/ast/sqlite.d.ts +69 -0
  140. package/dist/schema/db-schema/ast/sqlite.d.ts.map +1 -0
  141. package/dist/schema/db-schema/ast/sqlite.js +71 -0
  142. package/dist/schema/db-schema/ast/sqlite.js.map +1 -0
  143. package/dist/schema/db-schema/ast/validate.d.ts +3 -0
  144. package/dist/schema/db-schema/ast/validate.d.ts.map +1 -0
  145. package/dist/schema/db-schema/ast/validate.js +12 -0
  146. package/dist/schema/db-schema/ast/validate.js.map +1 -0
  147. package/dist/schema/db-schema/dsl/field-defs.d.ts +90 -0
  148. package/dist/schema/db-schema/dsl/field-defs.d.ts.map +1 -0
  149. package/dist/schema/db-schema/dsl/field-defs.js +87 -0
  150. package/dist/schema/db-schema/dsl/field-defs.js.map +1 -0
  151. package/dist/schema/db-schema/dsl/field-defs.test.d.ts +2 -0
  152. package/dist/schema/db-schema/dsl/field-defs.test.d.ts.map +1 -0
  153. package/dist/schema/db-schema/dsl/field-defs.test.js +29 -0
  154. package/dist/schema/db-schema/dsl/field-defs.test.js.map +1 -0
  155. package/dist/schema/db-schema/dsl/mod.d.ts +90 -0
  156. package/dist/schema/db-schema/dsl/mod.d.ts.map +1 -0
  157. package/dist/schema/db-schema/dsl/mod.js +41 -0
  158. package/dist/schema/db-schema/dsl/mod.js.map +1 -0
  159. package/dist/schema/db-schema/hash.d.ts +2 -0
  160. package/dist/schema/db-schema/hash.d.ts.map +1 -0
  161. package/dist/schema/db-schema/hash.js +14 -0
  162. package/dist/schema/db-schema/hash.js.map +1 -0
  163. package/dist/schema/db-schema/mod.d.ts +3 -0
  164. package/dist/schema/db-schema/mod.d.ts.map +1 -0
  165. package/dist/schema/db-schema/mod.js +3 -0
  166. package/dist/schema/db-schema/mod.js.map +1 -0
  167. package/dist/schema/events.d.ts +2 -0
  168. package/dist/schema/events.d.ts.map +1 -0
  169. package/dist/schema/events.js +2 -0
  170. package/dist/schema/events.js.map +1 -0
  171. package/dist/schema/mod.d.ts +5 -3
  172. package/dist/schema/mod.d.ts.map +1 -1
  173. package/dist/schema/mod.js +5 -3
  174. package/dist/schema/mod.js.map +1 -1
  175. package/dist/schema/schema-helpers.d.ts.map +1 -1
  176. package/dist/schema/schema-helpers.js +1 -1
  177. package/dist/schema/schema-helpers.js.map +1 -1
  178. package/dist/schema/schema.d.ts +30 -23
  179. package/dist/schema/schema.d.ts.map +1 -1
  180. package/dist/schema/schema.js +48 -35
  181. package/dist/schema/schema.js.map +1 -1
  182. package/dist/schema/sqlite-state.d.ts +12 -0
  183. package/dist/schema/sqlite-state.d.ts.map +1 -0
  184. package/dist/schema/sqlite-state.js +36 -0
  185. package/dist/schema/sqlite-state.js.map +1 -0
  186. package/dist/schema/system-tables.d.ts +179 -125
  187. package/dist/schema/system-tables.d.ts.map +1 -1
  188. package/dist/schema/system-tables.js +76 -41
  189. package/dist/schema/system-tables.js.map +1 -1
  190. package/dist/schema/table-def.d.ts +37 -109
  191. package/dist/schema/table-def.d.ts.map +1 -1
  192. package/dist/schema/table-def.js +23 -66
  193. package/dist/schema/table-def.js.map +1 -1
  194. package/dist/schema/view.d.ts +3 -0
  195. package/dist/schema/view.d.ts.map +1 -0
  196. package/dist/schema/view.js +3 -0
  197. package/dist/schema/view.js.map +1 -0
  198. package/dist/schema-management/common.d.ts +7 -7
  199. package/dist/schema-management/common.d.ts.map +1 -1
  200. package/dist/schema-management/common.js.map +1 -1
  201. package/dist/schema-management/migrations.d.ts +6 -6
  202. package/dist/schema-management/migrations.d.ts.map +1 -1
  203. package/dist/schema-management/migrations.js +19 -14
  204. package/dist/schema-management/migrations.js.map +1 -1
  205. package/dist/schema-management/validate-mutation-defs.d.ts +3 -3
  206. package/dist/schema-management/validate-mutation-defs.d.ts.map +1 -1
  207. package/dist/schema-management/validate-mutation-defs.js +17 -17
  208. package/dist/schema-management/validate-mutation-defs.js.map +1 -1
  209. package/dist/sql-queries/misc.d.ts.map +1 -1
  210. package/dist/sql-queries/sql-queries.d.ts +1 -1
  211. package/dist/sql-queries/sql-queries.d.ts.map +1 -1
  212. package/dist/sql-queries/sql-queries.js.map +1 -1
  213. package/dist/sql-queries/sql-query-builder.d.ts +1 -1
  214. package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
  215. package/dist/sql-queries/sql-query-builder.js.map +1 -1
  216. package/dist/sql-queries/types.d.ts +2 -1
  217. package/dist/sql-queries/types.d.ts.map +1 -1
  218. package/dist/sql-queries/types.js.map +1 -1
  219. package/dist/sync/ClientSessionSyncProcessor.d.ts +66 -0
  220. package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -0
  221. package/dist/sync/ClientSessionSyncProcessor.js +209 -0
  222. package/dist/sync/ClientSessionSyncProcessor.js.map +1 -0
  223. package/dist/sync/index.d.ts +1 -1
  224. package/dist/sync/index.d.ts.map +1 -1
  225. package/dist/sync/index.js +1 -1
  226. package/dist/sync/index.js.map +1 -1
  227. package/dist/sync/next/compact-events.d.ts.map +1 -1
  228. package/dist/sync/next/facts.d.ts +19 -19
  229. package/dist/sync/next/facts.d.ts.map +1 -1
  230. package/dist/sync/next/facts.js +3 -3
  231. package/dist/sync/next/facts.js.map +1 -1
  232. package/dist/sync/next/history-dag-common.d.ts +6 -7
  233. package/dist/sync/next/history-dag-common.d.ts.map +1 -1
  234. package/dist/sync/next/history-dag-common.js +4 -2
  235. package/dist/sync/next/history-dag-common.js.map +1 -1
  236. package/dist/sync/next/history-dag.d.ts.map +1 -1
  237. package/dist/sync/next/history-dag.js +2 -2
  238. package/dist/sync/next/history-dag.js.map +1 -1
  239. package/dist/sync/next/rebase-events.d.ts +10 -8
  240. package/dist/sync/next/rebase-events.d.ts.map +1 -1
  241. package/dist/sync/next/rebase-events.js +11 -8
  242. package/dist/sync/next/rebase-events.js.map +1 -1
  243. package/dist/sync/next/test/compact-events.calculator.test.js +38 -33
  244. package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
  245. package/dist/sync/next/test/compact-events.test.js +76 -76
  246. package/dist/sync/next/test/compact-events.test.js.map +1 -1
  247. package/dist/sync/next/test/{mutation-fixtures.d.ts → event-fixtures.d.ts} +29 -29
  248. package/dist/sync/next/test/event-fixtures.d.ts.map +1 -0
  249. package/dist/sync/next/test/{mutation-fixtures.js → event-fixtures.js} +67 -36
  250. package/dist/sync/next/test/event-fixtures.js.map +1 -0
  251. package/dist/sync/next/test/mod.d.ts +1 -1
  252. package/dist/sync/next/test/mod.d.ts.map +1 -1
  253. package/dist/sync/next/test/mod.js +1 -1
  254. package/dist/sync/next/test/mod.js.map +1 -1
  255. package/dist/sync/sync.d.ts +55 -20
  256. package/dist/sync/sync.d.ts.map +1 -1
  257. package/dist/sync/sync.js +7 -3
  258. package/dist/sync/sync.js.map +1 -1
  259. package/dist/sync/syncstate.d.ts +213 -82
  260. package/dist/sync/syncstate.d.ts.map +1 -1
  261. package/dist/sync/syncstate.js +319 -120
  262. package/dist/sync/syncstate.js.map +1 -1
  263. package/dist/sync/syncstate.test.js +295 -275
  264. package/dist/sync/syncstate.test.js.map +1 -1
  265. package/dist/sync/validate-push-payload.d.ts +2 -2
  266. package/dist/sync/validate-push-payload.d.ts.map +1 -1
  267. package/dist/sync/validate-push-payload.js +2 -2
  268. package/dist/sync/validate-push-payload.js.map +1 -1
  269. package/dist/util.d.ts +2 -2
  270. package/dist/util.d.ts.map +1 -1
  271. package/dist/version.d.ts +1 -1
  272. package/dist/version.d.ts.map +1 -1
  273. package/dist/version.js +1 -1
  274. package/dist/version.js.map +1 -1
  275. package/package.json +6 -6
  276. package/src/__tests__/fixture.ts +36 -15
  277. package/src/adapter-types.ts +111 -74
  278. package/src/debug-info.ts +1 -0
  279. package/src/devtools/devtools-messages-client-session.ts +141 -0
  280. package/src/devtools/devtools-messages-common.ts +115 -0
  281. package/src/devtools/devtools-messages-leader.ts +191 -0
  282. package/src/devtools/devtools-messages.ts +3 -243
  283. package/src/devtools/devtools-sessioninfo.ts +99 -0
  284. package/src/devtools/mod.ts +36 -0
  285. package/src/index.ts +4 -13
  286. package/src/leader-thread/LeaderSyncProcessor.ts +935 -0
  287. package/src/leader-thread/apply-event.ts +173 -0
  288. package/src/leader-thread/connection.ts +54 -9
  289. package/src/leader-thread/eventlog.ts +199 -0
  290. package/src/leader-thread/leader-worker-devtools.ts +212 -189
  291. package/src/leader-thread/make-leader-thread-layer.ts +143 -77
  292. package/src/leader-thread/mod.ts +1 -1
  293. package/src/leader-thread/recreate-db.ts +41 -30
  294. package/src/leader-thread/shutdown-channel.ts +2 -4
  295. package/src/leader-thread/types.ts +95 -51
  296. package/src/materializer-helper.ts +110 -0
  297. package/src/otel.ts +8 -0
  298. package/src/query-builder/api.ts +236 -85
  299. package/src/query-builder/astToSql.ts +232 -0
  300. package/src/query-builder/impl.test.ts +447 -78
  301. package/src/query-builder/impl.ts +209 -144
  302. package/src/query-builder/mod.ts +7 -0
  303. package/src/rehydrate-from-eventlog.ts +114 -0
  304. package/src/schema/EventDef.ts +216 -0
  305. package/src/schema/EventId.test.ts +12 -0
  306. package/src/schema/EventId.ts +75 -15
  307. package/src/schema/LiveStoreEvent.ts +239 -0
  308. package/src/schema/client-document-def.test.ts +239 -0
  309. package/src/schema/client-document-def.ts +444 -0
  310. package/src/schema/db-schema/ast/sqlite.ts +142 -0
  311. package/src/schema/db-schema/ast/validate.ts +13 -0
  312. package/src/schema/db-schema/dsl/__snapshots__/field-defs.test.ts.snap +206 -0
  313. package/src/schema/db-schema/dsl/field-defs.test.ts +35 -0
  314. package/src/schema/db-schema/dsl/field-defs.ts +242 -0
  315. package/src/schema/db-schema/dsl/mod.ts +222 -0
  316. package/src/schema/db-schema/hash.ts +14 -0
  317. package/src/schema/db-schema/mod.ts +2 -0
  318. package/src/schema/events.ts +1 -0
  319. package/src/schema/mod.ts +5 -3
  320. package/src/schema/schema-helpers.ts +1 -1
  321. package/src/schema/schema.ts +84 -62
  322. package/src/schema/sqlite-state.ts +62 -0
  323. package/src/schema/system-tables.ts +68 -50
  324. package/src/schema/table-def.ts +68 -214
  325. package/src/schema/view.ts +2 -0
  326. package/src/schema-management/common.ts +7 -7
  327. package/src/schema-management/migrations.ts +27 -24
  328. package/src/schema-management/validate-mutation-defs.ts +22 -24
  329. package/src/sql-queries/sql-queries.ts +1 -1
  330. package/src/sql-queries/sql-query-builder.ts +1 -2
  331. package/src/sql-queries/types.ts +3 -1
  332. package/src/sync/ClientSessionSyncProcessor.ts +332 -0
  333. package/src/sync/index.ts +1 -1
  334. package/src/sync/next/facts.ts +32 -33
  335. package/src/sync/next/history-dag-common.ts +9 -5
  336. package/src/sync/next/history-dag.ts +2 -2
  337. package/src/sync/next/rebase-events.ts +22 -16
  338. package/src/sync/next/test/compact-events.calculator.test.ts +45 -45
  339. package/src/sync/next/test/compact-events.test.ts +78 -78
  340. package/src/sync/next/test/event-fixtures.ts +219 -0
  341. package/src/sync/next/test/mod.ts +1 -1
  342. package/src/sync/sync.ts +51 -19
  343. package/src/sync/syncstate.test.ts +335 -308
  344. package/src/sync/syncstate.ts +394 -212
  345. package/src/sync/validate-push-payload.ts +7 -4
  346. package/src/version.ts +1 -1
  347. package/tmp/pack.tgz +0 -0
  348. package/tsconfig.json +2 -1
  349. package/dist/derived-mutations.d.ts +0 -109
  350. package/dist/derived-mutations.d.ts.map +0 -1
  351. package/dist/derived-mutations.js +0 -54
  352. package/dist/derived-mutations.js.map +0 -1
  353. package/dist/derived-mutations.test.d.ts +0 -2
  354. package/dist/derived-mutations.test.d.ts.map +0 -1
  355. package/dist/derived-mutations.test.js +0 -93
  356. package/dist/derived-mutations.test.js.map +0 -1
  357. package/dist/devtools/devtools-bridge.d.ts +0 -12
  358. package/dist/devtools/devtools-bridge.d.ts.map +0 -1
  359. package/dist/devtools/devtools-bridge.js +0 -2
  360. package/dist/devtools/devtools-bridge.js.map +0 -1
  361. package/dist/devtools/index.d.ts +0 -42
  362. package/dist/devtools/index.d.ts.map +0 -1
  363. package/dist/devtools/index.js +0 -48
  364. package/dist/devtools/index.js.map +0 -1
  365. package/dist/init-singleton-tables.d.ts +0 -4
  366. package/dist/init-singleton-tables.d.ts.map +0 -1
  367. package/dist/init-singleton-tables.js +0 -16
  368. package/dist/init-singleton-tables.js.map +0 -1
  369. package/dist/leader-thread/apply-mutation.d.ts +0 -8
  370. package/dist/leader-thread/apply-mutation.d.ts.map +0 -1
  371. package/dist/leader-thread/apply-mutation.js +0 -95
  372. package/dist/leader-thread/apply-mutation.js.map +0 -1
  373. package/dist/leader-thread/leader-sync-processor.d.ts +0 -47
  374. package/dist/leader-thread/leader-sync-processor.d.ts.map +0 -1
  375. package/dist/leader-thread/leader-sync-processor.js +0 -422
  376. package/dist/leader-thread/leader-sync-processor.js.map +0 -1
  377. package/dist/leader-thread/mutationlog.d.ts +0 -23
  378. package/dist/leader-thread/mutationlog.d.ts.map +0 -1
  379. package/dist/leader-thread/mutationlog.js +0 -27
  380. package/dist/leader-thread/mutationlog.js.map +0 -1
  381. package/dist/leader-thread/pull-queue-set.d.ts +0 -7
  382. package/dist/leader-thread/pull-queue-set.d.ts.map +0 -1
  383. package/dist/leader-thread/pull-queue-set.js +0 -39
  384. package/dist/leader-thread/pull-queue-set.js.map +0 -1
  385. package/dist/mutation.d.ts +0 -13
  386. package/dist/mutation.d.ts.map +0 -1
  387. package/dist/mutation.js +0 -57
  388. package/dist/mutation.js.map +0 -1
  389. package/dist/query-info.d.ts +0 -38
  390. package/dist/query-info.d.ts.map +0 -1
  391. package/dist/query-info.js +0 -7
  392. package/dist/query-info.js.map +0 -1
  393. package/dist/rehydrate-from-mutationlog.d.ts +0 -14
  394. package/dist/rehydrate-from-mutationlog.d.ts.map +0 -1
  395. package/dist/rehydrate-from-mutationlog.js +0 -72
  396. package/dist/rehydrate-from-mutationlog.js.map +0 -1
  397. package/dist/schema/MutationEvent.d.ts +0 -191
  398. package/dist/schema/MutationEvent.d.ts.map +0 -1
  399. package/dist/schema/MutationEvent.js +0 -56
  400. package/dist/schema/MutationEvent.js.map +0 -1
  401. package/dist/schema/mutations.d.ts +0 -107
  402. package/dist/schema/mutations.d.ts.map +0 -1
  403. package/dist/schema/mutations.js +0 -42
  404. package/dist/schema/mutations.js.map +0 -1
  405. package/dist/sync/client-session-sync-processor.d.ts +0 -45
  406. package/dist/sync/client-session-sync-processor.d.ts.map +0 -1
  407. package/dist/sync/client-session-sync-processor.js +0 -131
  408. package/dist/sync/client-session-sync-processor.js.map +0 -1
  409. package/dist/sync/next/test/mutation-fixtures.d.ts.map +0 -1
  410. package/dist/sync/next/test/mutation-fixtures.js.map +0 -1
  411. package/src/derived-mutations.test.ts +0 -101
  412. package/src/derived-mutations.ts +0 -166
  413. package/src/devtools/devtools-bridge.ts +0 -13
  414. package/src/devtools/index.ts +0 -48
  415. package/src/init-singleton-tables.ts +0 -24
  416. package/src/leader-thread/apply-mutation.ts +0 -143
  417. package/src/leader-thread/leader-sync-processor.ts +0 -666
  418. package/src/leader-thread/mutationlog.ts +0 -42
  419. package/src/leader-thread/pull-queue-set.ts +0 -58
  420. package/src/mutation.ts +0 -81
  421. package/src/query-info.ts +0 -78
  422. package/src/rehydrate-from-mutationlog.ts +0 -127
  423. package/src/schema/MutationEvent.ts +0 -161
  424. package/src/schema/mutations.ts +0 -192
  425. package/src/sync/client-session-sync-processor.ts +0 -207
  426. package/src/sync/next/test/mutation-fixtures.ts +0 -231
@@ -1,206 +1,575 @@
1
1
  import { Schema } from '@livestore/utils/effect'
2
2
  import { describe, expect, it } from 'vitest'
3
3
 
4
- import { DbSchema } from '../schema/mod.js'
4
+ import { State } from '../schema/mod.js'
5
+ import type { QueryBuilder } from './api.js'
5
6
  import { getResultSchema } from './impl.js'
6
7
 
7
- const todos = DbSchema.table(
8
- 'todos',
9
- {
10
- id: DbSchema.text({ primaryKey: true }),
11
- text: DbSchema.text({ default: '', nullable: false }),
12
- completed: DbSchema.boolean({ default: false, nullable: false }),
13
- status: DbSchema.text({ schema: Schema.Literal('active', 'completed') }),
14
- deletedAt: DbSchema.datetime({ nullable: true }),
8
+ const todos = State.SQLite.table({
9
+ name: 'todos',
10
+ columns: {
11
+ id: State.SQLite.text({ primaryKey: true }),
12
+ text: State.SQLite.text({ default: '', nullable: false }),
13
+ completed: State.SQLite.boolean({ default: false, nullable: false }),
14
+ status: State.SQLite.text({ schema: Schema.Literal('active', 'completed') }),
15
+ deletedAt: State.SQLite.datetime({ nullable: true }),
15
16
  // TODO consider leaning more into Effect schema
16
- // other: Schema.Number.pipe(DbSchema.asInteger),
17
+ // other: Schema.Number.pipe(State.SQLite.asInteger),
17
18
  },
18
- { deriveMutations: true },
19
- )
19
+ })
20
20
 
21
- const comments = DbSchema.table('comments', {
22
- id: DbSchema.text({ primaryKey: true }),
23
- text: DbSchema.text({ default: '', nullable: false }),
24
- todoId: DbSchema.text({}),
21
+ const todosWithIntId = State.SQLite.table({
22
+ name: 'todos_with_int_id',
23
+ columns: {
24
+ id: State.SQLite.integer({ primaryKey: true }),
25
+ text: State.SQLite.text({ default: '', nullable: false }),
26
+ status: State.SQLite.text({ schema: Schema.Literal('active', 'completed') }),
27
+ },
25
28
  })
26
29
 
27
- const db = { todos: todos.query, comments: comments.query }
30
+ const comments = State.SQLite.table({
31
+ name: 'comments',
32
+ columns: {
33
+ id: State.SQLite.text({ primaryKey: true }),
34
+ text: State.SQLite.text({ default: '', nullable: false }),
35
+ todoId: State.SQLite.text({}),
36
+ },
37
+ })
28
38
 
29
- describe('query builder', () => {
30
- describe('result schema', () => {
31
- it('should print the schema', () => {
32
- expect(String(getResultSchema(db.todos))).toMatchInlineSnapshot(`"ReadonlyArray<todos>"`)
33
- })
34
- })
39
+ const UiState = State.SQLite.clientDocument({
40
+ name: 'UiState',
41
+ schema: Schema.Struct({
42
+ filter: Schema.Literal('all', 'active', 'completed'),
43
+ }),
44
+ default: { value: { filter: 'all' } },
45
+ })
46
+
47
+ const UiStateWithDefaultId = State.SQLite.clientDocument({
48
+ name: 'UiState',
49
+ schema: Schema.Struct({
50
+ filter: Schema.Literal('all', 'active', 'completed'),
51
+ }),
52
+ default: {
53
+ id: 'static',
54
+ value: { filter: 'all' },
55
+ },
56
+ })
57
+
58
+ export const issue = State.SQLite.table({
59
+ name: 'issue',
60
+ columns: {
61
+ id: State.SQLite.integer({ primaryKey: true }),
62
+ title: State.SQLite.text({ default: '' }),
63
+ creator: State.SQLite.text({ default: '' }),
64
+ priority: State.SQLite.integer({ schema: Schema.Literal(0, 1, 2, 3, 4), default: 0 }),
65
+ created: State.SQLite.integer({ schema: Schema.DateFromNumber }),
66
+ deleted: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),
67
+ modified: State.SQLite.integer({ schema: Schema.DateFromNumber }),
68
+ kanbanorder: State.SQLite.text({ nullable: false, default: '' }),
69
+ },
70
+ indexes: [
71
+ { name: 'issue_kanbanorder', columns: ['kanbanorder'] },
72
+ { name: 'issue_created', columns: ['created'] },
73
+ ],
74
+ })
35
75
 
76
+ const db = { todos, todosWithIntId, comments, issue, UiState, UiStateWithDefaultId }
77
+
78
+ const dump = (qb: QueryBuilder<any, any, any>) => ({
79
+ bindValues: qb.asSql().bindValues,
80
+ query: qb.asSql().query,
81
+ schema: getResultSchema(qb).toString(),
82
+ })
83
+
84
+ describe('query builder', () => {
36
85
  describe('basic queries', () => {
37
86
  it('should handle simple SELECT queries', () => {
38
- expect(db.todos.asSql()).toMatchInlineSnapshot(`
87
+ expect(dump(db.todos)).toMatchInlineSnapshot(`
39
88
  {
40
89
  "bindValues": [],
41
90
  "query": "SELECT * FROM 'todos'",
91
+ "schema": "ReadonlyArray<todos>",
42
92
  }
43
93
  `)
44
94
 
45
- expect(db.todos.select('id', 'text').asSql()).toMatchInlineSnapshot(`
95
+ expect(dump(db.todos.select('id'))).toMatchInlineSnapshot(`
96
+ {
97
+ "bindValues": [],
98
+ "query": "SELECT id FROM 'todos'",
99
+ "schema": "ReadonlyArray<({ readonly id: string } <-> string)>",
100
+ }
101
+ `)
102
+
103
+ expect(dump(db.todos.select('id', 'text'))).toMatchInlineSnapshot(`
46
104
  {
47
105
  "bindValues": [],
48
106
  "query": "SELECT id, text FROM 'todos'",
107
+ "schema": "ReadonlyArray<{ readonly id: string; readonly text: string }>",
108
+ }
109
+ `)
110
+ })
111
+
112
+ it('should handle .first()', () => {
113
+ expect(dump(db.todos.select('id', 'text').first())).toMatchInlineSnapshot(`
114
+ {
115
+ "bindValues": [
116
+ 1,
117
+ ],
118
+ "query": "SELECT id, text FROM 'todos' LIMIT ?",
119
+ "schema": "(ReadonlyArray<{ readonly id: string; readonly text: string }> <-> { readonly id: string; readonly text: string })",
120
+ }
121
+ `)
122
+
123
+ expect(dump(db.todos.select('id', 'text').first({ fallback: () => undefined }))).toMatchInlineSnapshot(`
124
+ {
125
+ "bindValues": [
126
+ 1,
127
+ ],
128
+ "query": "SELECT id, text FROM 'todos' LIMIT ?",
129
+ "schema": "(ReadonlyArray<{ readonly id: string; readonly text: string }> | readonly [undefined] <-> { readonly id: string; readonly text: string } | undefined)",
49
130
  }
50
131
  `)
51
132
  })
52
133
 
53
134
  it('should handle WHERE clauses', () => {
54
- expect(db.todos.select('id', 'text').where('completed', true).asSql()).toMatchInlineSnapshot(`
135
+ expect(dump(db.todos.select('id', 'text').where('completed', true))).toMatchInlineSnapshot(`
55
136
  {
56
137
  "bindValues": [
57
138
  1,
58
139
  ],
59
140
  "query": "SELECT id, text FROM 'todos' WHERE completed = ?",
141
+ "schema": "ReadonlyArray<{ readonly id: string; readonly text: string }>",
60
142
  }
61
143
  `)
62
- expect(db.todos.select('id', 'text').where('completed', '!=', true).asSql()).toMatchInlineSnapshot(`
144
+ expect(dump(db.todos.select('id', 'text').where('completed', '!=', true))).toMatchInlineSnapshot(`
63
145
  {
64
146
  "bindValues": [
65
147
  1,
66
148
  ],
67
149
  "query": "SELECT id, text FROM 'todos' WHERE completed != ?",
150
+ "schema": "ReadonlyArray<{ readonly id: string; readonly text: string }>",
68
151
  }
69
152
  `)
70
- expect(db.todos.select('id', 'text').where({ completed: true }).asSql()).toMatchInlineSnapshot(`
153
+ expect(dump(db.todos.select('id', 'text').where({ completed: true }))).toMatchInlineSnapshot(`
71
154
  {
72
155
  "bindValues": [
73
156
  1,
74
157
  ],
75
158
  "query": "SELECT id, text FROM 'todos' WHERE completed = ?",
159
+ "schema": "ReadonlyArray<{ readonly id: string; readonly text: string }>",
76
160
  }
77
161
  `)
78
- expect(db.todos.select('id', 'text').where({ completed: undefined }).asSql()).toMatchInlineSnapshot(`
162
+ expect(dump(db.todos.select('id', 'text').where({ completed: undefined }))).toMatchInlineSnapshot(`
79
163
  {
80
164
  "bindValues": [],
81
165
  "query": "SELECT id, text FROM 'todos'",
166
+ "schema": "ReadonlyArray<{ readonly id: string; readonly text: string }>",
82
167
  }
83
168
  `)
84
- expect(
85
- db.todos
86
- .select('id', 'text')
87
- .where({ deletedAt: { op: '<=', value: new Date('2024-01-01') } })
88
- .asSql(),
89
- ).toMatchInlineSnapshot(`
169
+ expect(dump(db.todos.select('id', 'text').where({ deletedAt: { op: '<=', value: new Date('2024-01-01') } })))
170
+ .toMatchInlineSnapshot(`
171
+ {
172
+ "bindValues": [
173
+ "2024-01-01T00:00:00.000Z",
174
+ ],
175
+ "query": "SELECT id, text FROM 'todos' WHERE deletedAt <= ?",
176
+ "schema": "ReadonlyArray<{ readonly id: string; readonly text: string }>",
177
+ }
178
+ `)
179
+ expect(dump(db.todos.select('id', 'text').where({ status: { op: 'IN', value: ['active'] } })))
180
+ .toMatchInlineSnapshot(`
181
+ {
182
+ "bindValues": [
183
+ "active",
184
+ ],
185
+ "query": "SELECT id, text FROM 'todos' WHERE status IN (?)",
186
+ "schema": "ReadonlyArray<{ readonly id: string; readonly text: string }>",
187
+ }
188
+ `)
189
+ expect(dump(db.todos.select('id', 'text').where({ status: { op: 'NOT IN', value: ['active', 'completed'] } })))
190
+ .toMatchInlineSnapshot(`
191
+ {
192
+ "bindValues": [
193
+ "active",
194
+ "completed",
195
+ ],
196
+ "query": "SELECT id, text FROM 'todos' WHERE status NOT IN (?, ?)",
197
+ "schema": "ReadonlyArray<{ readonly id: string; readonly text: string }>",
198
+ }
199
+ `)
200
+ })
201
+
202
+ it('should handle OFFSET and LIMIT clauses', () => {
203
+ expect(dump(db.todos.select('id', 'text').where('completed', true).offset(10).limit(10))).toMatchInlineSnapshot(`
90
204
  {
91
205
  "bindValues": [
92
- "2024-01-01T00:00:00.000Z",
206
+ 1,
207
+ 10,
208
+ 10,
93
209
  ],
94
- "query": "SELECT id, text FROM 'todos' WHERE deletedAt <= ?",
210
+ "query": "SELECT id, text FROM 'todos' WHERE completed = ? OFFSET ? LIMIT ?",
211
+ "schema": "ReadonlyArray<{ readonly id: string; readonly text: string }>",
95
212
  }
96
213
  `)
97
- expect(
98
- db.todos
99
- .select('id', 'text')
100
- .where({ status: { op: 'IN', value: ['active'] } })
101
- .asSql(),
102
- ).toMatchInlineSnapshot(`
214
+ })
215
+
216
+ it('should handle OFFSET and LIMIT clauses correctly', () => {
217
+ // Test with both offset and limit
218
+ expect(dump(db.todos.select('id', 'text').where('completed', true).offset(5).limit(10))).toMatchInlineSnapshot(`
103
219
  {
104
220
  "bindValues": [
105
- "active",
221
+ 1,
222
+ 5,
223
+ 10,
106
224
  ],
107
- "query": "SELECT id, text FROM 'todos' WHERE status IN (?)",
225
+ "query": "SELECT id, text FROM 'todos' WHERE completed = ? OFFSET ? LIMIT ?",
226
+ "schema": "ReadonlyArray<{ readonly id: string; readonly text: string }>",
108
227
  }
109
228
  `)
110
- expect(
111
- db.todos
112
- .select('id', 'text')
113
- .where({ status: { op: 'NOT IN', value: ['active', 'completed'] } })
114
- .asSql(),
115
- ).toMatchInlineSnapshot(`
229
+
230
+ // Test with only offset
231
+ expect(dump(db.todos.select('id', 'text').where('completed', true).offset(5))).toMatchInlineSnapshot(`
116
232
  {
117
233
  "bindValues": [
118
- "active",
119
- "completed",
234
+ 1,
235
+ 5,
120
236
  ],
121
- "query": "SELECT id, text FROM 'todos' WHERE status NOT IN (?, ?)",
237
+ "query": "SELECT id, text FROM 'todos' WHERE completed = ? OFFSET ?",
238
+ "schema": "ReadonlyArray<{ readonly id: string; readonly text: string }>",
122
239
  }
123
240
  `)
124
- })
125
241
 
126
- it('should handle OFFSET and LIMIT clauses', () => {
127
- expect(db.todos.select('id', 'text').where('completed', true).offset(10).limit(10).asSql())
128
- .toMatchInlineSnapshot(`
129
- {
130
- "bindValues": [
131
- 1,
132
- 10,
133
- 10,
134
- ],
135
- "query": "SELECT id, text FROM 'todos' WHERE completed = ? OFFSET ? LIMIT ?",
136
- }
137
- `)
242
+ // Test with only limit
243
+ expect(dump(db.todos.select('id', 'text').where('completed', true).limit(10))).toMatchInlineSnapshot(`
244
+ {
245
+ "bindValues": [
246
+ 1,
247
+ 10,
248
+ ],
249
+ "query": "SELECT id, text FROM 'todos' WHERE completed = ? LIMIT ?",
250
+ "schema": "ReadonlyArray<{ readonly id: string; readonly text: string }>",
251
+ }
252
+ `)
138
253
  })
139
254
 
140
255
  it('should handle COUNT queries', () => {
141
- expect(db.todos.count().asSql()).toMatchInlineSnapshot(`
256
+ expect(dump(db.todos.count())).toMatchInlineSnapshot(`
142
257
  {
143
258
  "bindValues": [],
144
259
  "query": "SELECT COUNT(*) as count FROM 'todos'",
260
+ "schema": "(ReadonlyArray<({ readonly count: number } <-> number)> <-> number)",
145
261
  }
146
262
  `)
147
- expect(db.todos.count().where('completed', true).asSql()).toMatchInlineSnapshot(`
263
+ expect(dump(db.todos.count().where('completed', true))).toMatchInlineSnapshot(`
148
264
  {
149
265
  "bindValues": [
150
266
  1,
151
267
  ],
152
268
  "query": "SELECT COUNT(*) as count FROM 'todos' WHERE completed = ?",
269
+ "schema": "(ReadonlyArray<({ readonly count: number } <-> number)> <-> number)",
153
270
  }
154
271
  `)
155
272
  })
156
273
 
157
274
  it('should handle NULL comparisons', () => {
158
- expect(db.todos.select('id', 'text').where('deletedAt', '=', null).asSql()).toMatchInlineSnapshot(`
275
+ expect(dump(db.todos.select('id', 'text').where('deletedAt', '=', null))).toMatchInlineSnapshot(`
159
276
  {
160
277
  "bindValues": [],
161
278
  "query": "SELECT id, text FROM 'todos' WHERE deletedAt IS NULL",
279
+ "schema": "ReadonlyArray<{ readonly id: string; readonly text: string }>",
162
280
  }
163
281
  `)
164
- expect(db.todos.select('id', 'text').where('deletedAt', '!=', null).asSql()).toMatchInlineSnapshot(`
282
+ expect(dump(db.todos.select('id', 'text').where('deletedAt', '!=', null))).toMatchInlineSnapshot(`
165
283
  {
166
284
  "bindValues": [],
167
285
  "query": "SELECT id, text FROM 'todos' WHERE deletedAt IS NOT NULL",
286
+ "schema": "ReadonlyArray<{ readonly id: string; readonly text: string }>",
168
287
  }
169
288
  `)
170
289
  })
171
290
 
172
291
  it('should handle orderBy', () => {
173
- expect(db.todos.orderBy('completed', 'desc').asSql()).toMatchInlineSnapshot(`
292
+ expect(dump(db.todos.orderBy('completed', 'desc'))).toMatchInlineSnapshot(`
174
293
  {
175
294
  "bindValues": [],
176
295
  "query": "SELECT * FROM 'todos' ORDER BY completed desc",
296
+ "schema": "ReadonlyArray<todos>",
177
297
  }
178
298
  `)
179
299
 
180
- expect(db.todos.orderBy([{ col: 'completed', direction: 'desc' }]).asSql()).toMatchInlineSnapshot(`
300
+ expect(dump(db.todos.orderBy([{ col: 'completed', direction: 'desc' }]))).toMatchInlineSnapshot(`
181
301
  {
182
302
  "bindValues": [],
183
303
  "query": "SELECT * FROM 'todos' ORDER BY completed desc",
304
+ "schema": "ReadonlyArray<todos>",
184
305
  }
185
306
  `)
186
307
 
187
- expect(db.todos.orderBy([]).asSql()).toMatchInlineSnapshot(`
308
+ expect(dump(db.todos.orderBy([]))).toMatchInlineSnapshot(`
188
309
  {
189
310
  "bindValues": [],
190
311
  "query": "SELECT * FROM 'todos'",
312
+ "schema": "ReadonlyArray<todos>",
191
313
  }
192
314
  `)
193
315
  })
194
316
  })
195
317
 
196
- describe('row queries', () => {
197
- it('should handle row queries', () => {
198
- expect(db.todos.row('123', { insertValues: { status: 'completed' } }).asSql()).toMatchInlineSnapshot(`
318
+ // describe('getOrCreate queries', () => {
319
+ // it('should handle getOrCreate queries', () => {
320
+ // expect(dump(db.UiState.getOrCreate('sessionid-1'))).toMatchInlineSnapshot(`
321
+ // {
322
+ // "bindValues": [
323
+ // "sessionid-1",
324
+ // ],
325
+ // "query": "SELECT * FROM 'UiState' WHERE id = ?",
326
+ // "schema": "...", // TODO determine schema
327
+ // }
328
+ // `)
329
+ // })
330
+
331
+ // it('should handle getOrCreate queries with default id', () => {
332
+ // expect(dump(db.UiStateWithDefaultId.getOrCreate())).toMatchInlineSnapshot(`
333
+ // {
334
+ // "bindValues": [],
335
+ // "query": "SELECT * FROM 'UiState' WHERE id = ?",
336
+ // "schema": "...", // TODO determine schema
337
+ // }
338
+ // `)
339
+ // })
340
+ // // it('should handle row queries with numbers', () => {
341
+ // // expect(dump(db.todosWithIntId.getOrCreate(123, { insertValues: { status: 'active' } }))).toMatchInlineSnapshot(`
342
+ // // {
343
+ // // "bindValues": [
344
+ // // 123,
345
+ // // ],
346
+ // // "query": "SELECT * FROM 'todos_with_int_id' WHERE id = ?",
347
+ // // "schema": "...", // TODO determine schema
348
+ // // }
349
+ // // `)
350
+ // // })
351
+ // })
352
+
353
+ describe('write operations', () => {
354
+ it('should handle INSERT queries', () => {
355
+ expect(dump(db.todos.insert({ id: '123', text: 'Buy milk', status: 'active' }))).toMatchInlineSnapshot(`
356
+ {
357
+ "bindValues": [
358
+ "123",
359
+ "Buy milk",
360
+ "active",
361
+ ],
362
+ "query": "INSERT INTO 'todos' (id, text, status) VALUES (?, ?, ?)",
363
+ "schema": "number",
364
+ }
365
+ `)
366
+ })
367
+
368
+ it('should handle INSERT queries with undefined values', () => {
369
+ expect(dump(db.todos.insert({ id: '123', text: 'Buy milk', status: 'active', completed: undefined })))
370
+ .toMatchInlineSnapshot(`
199
371
  {
200
372
  "bindValues": [
201
373
  "123",
374
+ "Buy milk",
375
+ "active",
376
+ ],
377
+ "query": "INSERT INTO 'todos' (id, text, status) VALUES (?, ?, ?)",
378
+ "schema": "number",
379
+ }
380
+ `)
381
+ })
382
+
383
+ // Test helped to catch a bindValues ordering bug
384
+ it('should handle INSERT queries (issue)', () => {
385
+ expect(
386
+ dump(
387
+ db.issue.insert({
388
+ id: 1,
389
+ title: 'Revert the user profile page',
390
+ priority: 2,
391
+ created: new Date('2024-08-01T17:15:20.507Z'),
392
+ modified: new Date('2024-12-29T17:15:20.507Z'),
393
+ kanbanorder: 'a2',
394
+ creator: 'John Doe',
395
+ }),
396
+ ),
397
+ ).toMatchInlineSnapshot(`
398
+ {
399
+ "bindValues": [
400
+ 1,
401
+ "Revert the user profile page",
402
+ 2,
403
+ 1722532520507,
404
+ 1735492520507,
405
+ "a2",
406
+ "John Doe",
407
+ ],
408
+ "query": "INSERT INTO 'issue' (id, title, priority, created, modified, kanbanorder, creator) VALUES (?, ?, ?, ?, ?, ?, ?)",
409
+ "schema": "number",
410
+ }
411
+ `)
412
+ })
413
+
414
+ it('should handle UPDATE queries', () => {
415
+ expect(dump(db.todos.update({ status: 'completed' }).where({ id: '123' }))).toMatchInlineSnapshot(`
416
+ {
417
+ "bindValues": [
418
+ "completed",
419
+ "123",
420
+ ],
421
+ "query": "UPDATE 'todos' SET status = ? WHERE id = ?",
422
+ "schema": "number",
423
+ }
424
+ `)
425
+
426
+ // empty update set
427
+ expect(dump(db.todos.update({}).where({ id: '123' }))).toMatchInlineSnapshot(`
428
+ {
429
+ "bindValues": [],
430
+ "query": "SELECT 1",
431
+ "schema": "number",
432
+ }
433
+ `)
434
+ })
435
+
436
+ it('should handle UPDATE queries with undefined values', () => {
437
+ expect(dump(db.todos.update({ status: undefined, text: 'some text' }).where({ id: '123' })))
438
+ .toMatchInlineSnapshot(`
439
+ {
440
+ "bindValues": [
441
+ "some text",
442
+ "123",
443
+ ],
444
+ "query": "UPDATE 'todos' SET text = ? WHERE id = ?",
445
+ "schema": "number",
446
+ }
447
+ `)
448
+ })
449
+
450
+ it('should handle UPDATE queries with undefined values (issue)', () => {
451
+ expect(dump(db.issue.update({ priority: 2, creator: 'John Doe' }).where({ id: 1 }))).toMatchInlineSnapshot(`
452
+ {
453
+ "bindValues": [
454
+ 2,
455
+ "John Doe",
456
+ 1,
457
+ ],
458
+ "query": "UPDATE 'issue' SET priority = ?, creator = ? WHERE id = ?",
459
+ "schema": "number",
460
+ }
461
+ `)
462
+ })
463
+
464
+ it('should handle DELETE queries', () => {
465
+ expect(dump(db.todos.delete().where({ status: 'completed' }))).toMatchInlineSnapshot(`
466
+ {
467
+ "bindValues": [
468
+ "completed",
469
+ ],
470
+ "query": "DELETE FROM 'todos' WHERE status = ?",
471
+ "schema": "number",
472
+ }
473
+ `)
474
+ })
475
+
476
+ it('should handle INSERT with ON CONFLICT', () => {
477
+ expect(dump(db.todos.insert({ id: '123', text: 'Buy milk', status: 'active' }).onConflict('id', 'ignore')))
478
+ .toMatchInlineSnapshot(`
479
+ {
480
+ "bindValues": [
481
+ "123",
482
+ "Buy milk",
483
+ "active",
484
+ ],
485
+ "query": "INSERT INTO 'todos' (id, text, status) VALUES (?, ?, ?) ON CONFLICT (id) DO NOTHING",
486
+ "schema": "number",
487
+ }
488
+ `)
489
+
490
+ expect(
491
+ dump(
492
+ db.todos
493
+ .insert({ id: '123', text: 'Buy milk', status: 'active' })
494
+ .onConflict('id', 'update', { text: 'Buy soy milk', status: 'active' }),
495
+ ),
496
+ ).toMatchInlineSnapshot(`
497
+ {
498
+ "bindValues": [
499
+ "123",
500
+ "Buy milk",
501
+ "active",
502
+ "Buy soy milk",
503
+ "active",
504
+ ],
505
+ "query": "INSERT INTO 'todos' (id, text, status) VALUES (?, ?, ?) ON CONFLICT (id) DO UPDATE SET text = ?, status = ?",
506
+ "schema": "number",
507
+ }
508
+ `)
509
+
510
+ expect(dump(db.todos.insert({ id: '123', text: 'Buy milk', status: 'active' }).onConflict('id', 'replace')))
511
+ .toMatchInlineSnapshot(`
512
+ {
513
+ "bindValues": [
514
+ "123",
515
+ "Buy milk",
516
+ "active",
517
+ ],
518
+ "query": "INSERT OR REPLACE INTO 'todos' (id, text, status) VALUES (?, ?, ?)",
519
+ "schema": "number",
520
+ }
521
+ `)
522
+ })
523
+
524
+ it('should handle ON CONFLICT with multiple columns', () => {
525
+ expect(
526
+ dump(db.todos.insert({ id: '123', text: 'Buy milk', status: 'active' }).onConflict(['id', 'status'], 'ignore')),
527
+ ).toMatchInlineSnapshot(`
528
+ {
529
+ "bindValues": [
530
+ "123",
531
+ "Buy milk",
532
+ "active",
533
+ ],
534
+ "query": "INSERT INTO 'todos' (id, text, status) VALUES (?, ?, ?) ON CONFLICT (id, status) DO NOTHING",
535
+ "schema": "number",
536
+ }
537
+ `)
538
+ })
539
+
540
+ it('should handle RETURNING clause', () => {
541
+ expect(dump(db.todos.insert({ id: '123', text: 'Buy milk', status: 'active' }).returning('id')))
542
+ .toMatchInlineSnapshot(`
543
+ {
544
+ "bindValues": [
545
+ "123",
546
+ "Buy milk",
547
+ "active",
548
+ ],
549
+ "query": "INSERT INTO 'todos' (id, text, status) VALUES (?, ?, ?) RETURNING id",
550
+ "schema": "ReadonlyArray<{ readonly id: string }>",
551
+ }
552
+ `)
553
+
554
+ expect(dump(db.todos.update({ status: 'completed' }).where({ id: '123' }).returning('id')))
555
+ .toMatchInlineSnapshot(`
556
+ {
557
+ "bindValues": [
558
+ "completed",
559
+ "123",
560
+ ],
561
+ "query": "UPDATE 'todos' SET status = ? WHERE id = ? RETURNING id",
562
+ "schema": "ReadonlyArray<{ readonly id: string }>",
563
+ }
564
+ `)
565
+
566
+ expect(dump(db.todos.delete().where({ status: 'completed' }).returning('id'))).toMatchInlineSnapshot(`
567
+ {
568
+ "bindValues": [
569
+ "completed",
202
570
  ],
203
- "query": "SELECT * FROM 'todos' WHERE id = ?",
571
+ "query": "DELETE FROM 'todos' WHERE status = ? RETURNING id",
572
+ "schema": "ReadonlyArray<{ readonly id: string }>",
204
573
  }
205
574
  `)
206
575
  })