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

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
@@ -0,0 +1,190 @@
1
+ import { shouldNeverHappen } from '@livestore/utils';
2
+ import { Schema } from '@livestore/utils/effect';
3
+ import { SessionIdSymbol } from '../adapter-types.js';
4
+ // Helper functions for SQL generation
5
+ const formatWhereClause = (whereConditions, tableDef, bindValues) => {
6
+ if (whereConditions.length === 0)
7
+ return '';
8
+ const whereClause = whereConditions
9
+ .map(({ col, op, value }) => {
10
+ // Handle NULL values
11
+ if (value === null) {
12
+ if (op !== '=' && op !== '!=') {
13
+ throw new Error(`Unsupported operator for NULL value: ${op}`);
14
+ }
15
+ const opStmt = op === '=' ? 'IS' : 'IS NOT';
16
+ return `${col} ${opStmt} NULL`;
17
+ }
18
+ // Get column definition and encode value
19
+ const colDef = tableDef.sqliteDef.columns[col];
20
+ if (colDef === undefined) {
21
+ throw new Error(`Column ${col} not found`);
22
+ }
23
+ // Handle array values for IN/NOT IN operators
24
+ const isArray = op === 'IN' || op === 'NOT IN';
25
+ if (isArray) {
26
+ // Verify value is an array
27
+ if (!Array.isArray(value)) {
28
+ return shouldNeverHappen(`Expected array value for ${op} operator but got`, value);
29
+ }
30
+ // Handle empty arrays
31
+ if (value.length === 0) {
32
+ return op === 'IN' ? '0=1' : '1=1';
33
+ }
34
+ const encodedValues = value.map((v) => Schema.encodeSync(colDef.schema)(v));
35
+ bindValues.push(...encodedValues);
36
+ const placeholders = encodedValues.map(() => '?').join(', ');
37
+ return `${col} ${op} (${placeholders})`;
38
+ }
39
+ else {
40
+ const encodedValue = Schema.encodeSync(colDef.schema)(value);
41
+ bindValues.push(encodedValue);
42
+ return `${col} ${op} ?`;
43
+ }
44
+ })
45
+ .join(' AND ');
46
+ return `WHERE ${whereClause}`;
47
+ };
48
+ const formatReturningClause = (returning) => {
49
+ if (!returning || returning.length === 0)
50
+ return '';
51
+ return ` RETURNING ${returning.join(', ')}`;
52
+ };
53
+ export const astToSql = (ast) => {
54
+ const bindValues = [];
55
+ // INSERT query
56
+ if (ast._tag === 'InsertQuery') {
57
+ const columns = Object.keys(ast.values);
58
+ const placeholders = columns.map(() => '?').join(', ');
59
+ const encodedValues = Schema.encodeSync(ast.tableDef.insertSchema)(ast.values);
60
+ // Ensure bind values are added in the same order as columns
61
+ columns.forEach((col) => {
62
+ bindValues.push(encodedValues[col]);
63
+ });
64
+ let insertVerb = 'INSERT';
65
+ let conflictClause = ''; // Store the ON CONFLICT clause separately
66
+ // Handle ON CONFLICT clause
67
+ if (ast.onConflict) {
68
+ // Handle REPLACE specifically as it changes the INSERT verb
69
+ if (ast.onConflict.action._tag === 'replace') {
70
+ insertVerb = 'INSERT OR REPLACE';
71
+ // For REPLACE, the conflict target is implied and no further clause is needed
72
+ }
73
+ else {
74
+ // Build the ON CONFLICT clause for IGNORE or UPDATE
75
+ conflictClause = ` ON CONFLICT (${ast.onConflict.targets.join(', ')}) `;
76
+ if (ast.onConflict.action._tag === 'ignore') {
77
+ conflictClause += 'DO NOTHING';
78
+ }
79
+ else {
80
+ // Handle the update record case
81
+ const updateValues = ast.onConflict.action.update;
82
+ const updateCols = Object.keys(updateValues);
83
+ if (updateCols.length === 0) {
84
+ throw new Error('No update columns provided for ON CONFLICT DO UPDATE');
85
+ }
86
+ const updates = updateCols
87
+ .map((col) => {
88
+ const value = updateValues[col];
89
+ // If the value is undefined, use excluded.col
90
+ return value === undefined ? `${col} = excluded.${col}` : `${col} = ?`;
91
+ })
92
+ .join(', ');
93
+ // Add values for the parameters
94
+ updateCols.forEach((col) => {
95
+ const value = updateValues[col];
96
+ if (value !== undefined) {
97
+ const colDef = ast.tableDef.sqliteDef.columns[col];
98
+ if (colDef === undefined) {
99
+ throw new Error(`Column ${col} not found`);
100
+ }
101
+ const encodedValue = Schema.encodeSync(colDef.schema)(value);
102
+ bindValues.push(encodedValue);
103
+ }
104
+ });
105
+ conflictClause += `DO UPDATE SET ${updates}`;
106
+ }
107
+ }
108
+ }
109
+ // Construct the main query part
110
+ let query = `${insertVerb} INTO '${ast.tableDef.sqliteDef.name}' (${columns.join(', ')}) VALUES (${placeholders})`;
111
+ // Append the conflict clause if it was generated (i.e., not for REPLACE)
112
+ query += conflictClause;
113
+ query += formatReturningClause(ast.returning);
114
+ return { query, bindValues };
115
+ }
116
+ // UPDATE query
117
+ if (ast._tag === 'UpdateQuery') {
118
+ const setColumns = Object.keys(ast.values);
119
+ if (setColumns.length === 0) {
120
+ console.warn(`UPDATE query requires at least one column to set (for table ${ast.tableDef.sqliteDef.name}). Running no-op query instead to skip this update query.`);
121
+ return { query: 'SELECT 1', bindValues: [] };
122
+ // return shouldNeverHappen('UPDATE query requires at least one column to set.')
123
+ }
124
+ const encodedValues = Schema.encodeSync(Schema.partial(ast.tableDef.rowSchema))(ast.values);
125
+ // Ensure bind values are added in the same order as columns
126
+ setColumns.forEach((col) => {
127
+ bindValues.push(encodedValues[col]);
128
+ });
129
+ let query = `UPDATE '${ast.tableDef.sqliteDef.name}' SET ${setColumns.map((col) => `${col} = ?`).join(', ')}`;
130
+ const whereClause = formatWhereClause(ast.where, ast.tableDef, bindValues);
131
+ if (whereClause)
132
+ query += ` ${whereClause}`;
133
+ query += formatReturningClause(ast.returning);
134
+ return { query, bindValues };
135
+ }
136
+ // DELETE query
137
+ if (ast._tag === 'DeleteQuery') {
138
+ let query = `DELETE FROM '${ast.tableDef.sqliteDef.name}'`;
139
+ const whereClause = formatWhereClause(ast.where, ast.tableDef, bindValues);
140
+ if (whereClause)
141
+ query += ` ${whereClause}`;
142
+ query += formatReturningClause(ast.returning);
143
+ return { query, bindValues };
144
+ }
145
+ // COUNT query
146
+ if (ast._tag === 'CountQuery') {
147
+ const query = [
148
+ `SELECT COUNT(*) as count FROM '${ast.tableDef.sqliteDef.name}'`,
149
+ formatWhereClause(ast.where, ast.tableDef, bindValues),
150
+ ]
151
+ .filter((clause) => clause.length > 0)
152
+ .join(' ');
153
+ return { query, bindValues };
154
+ }
155
+ // ROW query
156
+ if (ast._tag === 'RowQuery') {
157
+ // Handle the id value by encoding it with the id column schema
158
+ const idColDef = ast.tableDef.sqliteDef.columns.id;
159
+ if (idColDef === undefined) {
160
+ throw new Error('Column id not found for ROW query');
161
+ }
162
+ // NOTE we're not encoding the id if it's the session id symbol, which needs to be taken care of by the caller
163
+ const encodedId = ast.id === SessionIdSymbol ? ast.id : Schema.encodeSync(idColDef.schema)(ast.id);
164
+ return {
165
+ query: `SELECT * FROM '${ast.tableDef.sqliteDef.name}' WHERE id = ?`,
166
+ bindValues: [encodedId],
167
+ };
168
+ }
169
+ // SELECT query
170
+ const columnsStmt = ast.select.columns.length === 0 ? '*' : ast.select.columns.join(', ');
171
+ const selectStmt = `SELECT ${columnsStmt}`;
172
+ const fromStmt = `FROM '${ast.tableDef.sqliteDef.name}'`;
173
+ const whereStmt = formatWhereClause(ast.where, ast.tableDef, bindValues);
174
+ const orderByStmt = ast.orderBy.length > 0
175
+ ? `ORDER BY ${ast.orderBy.map(({ col, direction }) => `${col} ${direction}`).join(', ')}`
176
+ : '';
177
+ const limitStmt = ast.limit._tag === 'Some' ? `LIMIT ?` : '';
178
+ const offsetStmt = ast.offset._tag === 'Some' ? `OFFSET ?` : '';
179
+ // Push offset and limit values in the correct order matching the query string
180
+ if (ast.offset._tag === 'Some')
181
+ bindValues.push(ast.offset.value);
182
+ if (ast.limit._tag === 'Some')
183
+ bindValues.push(ast.limit.value);
184
+ const query = [selectStmt, fromStmt, whereStmt, orderByStmt, offsetStmt, limitStmt]
185
+ .map((clause) => clause.trim())
186
+ .filter((clause) => clause.length > 0)
187
+ .join(' ');
188
+ return { query, bindValues };
189
+ };
190
+ //# sourceMappingURL=astToSql.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"astToSql.js","sourceRoot":"","sources":["../../src/query-builder/astToSql.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,7 @@
1
1
  import { Schema } from '@livestore/utils/effect';
2
- import type { QueryInfo } from '../query-info.js';
3
- import type { DbSchema } from '../schema/mod.js';
2
+ import type { State } from '../schema/mod.js';
4
3
  import type { QueryBuilder, QueryBuilderAst } from './api.js';
5
- export declare const makeQueryBuilder: <TResult, TTableDef extends DbSchema.TableDefBase>(tableDef: TTableDef, ast?: QueryBuilderAst) => QueryBuilder<TResult, TTableDef, never, QueryInfo.None>;
4
+ export declare const makeQueryBuilder: <TResult, TTableDef extends State.SQLite.TableDefBase>(tableDef: TTableDef, ast?: QueryBuilderAst) => QueryBuilder<TResult, TTableDef, never>;
6
5
  export declare const invalidQueryBuilder: (msg?: string) => never;
7
- export declare const getResultSchema: (qb: QueryBuilder<any, any, any>) => Schema.Array$<Schema.Schema<any, any, never>> | Schema.SchemaClass<any, readonly any[], never> | Schema.SchemaClass<number, readonly {
8
- readonly count: number;
9
- }[], never> | Schema.SchemaClass<any, readonly {
10
- readonly value: any;
11
- }[], never>;
6
+ export declare const getResultSchema: (qb: QueryBuilder<any, any, any>) => Schema.Schema<any>;
12
7
  //# sourceMappingURL=impl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"impl.d.ts","sourceRoot":"","sources":["../../src/query-builder/impl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAEnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAG7D,eAAO,MAAM,gBAAgB,GAAI,OAAO,EAAE,SAAS,SAAS,QAAQ,CAAC,YAAY,YACrE,SAAS,QACd,eAAe,KACnB,YAAY,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,CA6JxD,CAAA;AA+FD,eAAO,MAAM,mBAAmB,SAAU,MAAM,UAE/C,CAAA;AAED,eAAO,MAAM,eAAe,OAAQ,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;;;;WAkB9D,CAAA"}
1
+ {"version":3,"file":"impl.d.ts","sourceRoot":"","sources":["../../src/query-builder/impl.ts"],"names":[],"mappings":"AACA,OAAO,EAA4B,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAE1E,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAI7D,eAAO,MAAM,gBAAgB,GAAI,OAAO,EAAE,SAAS,SAAS,KAAK,CAAC,MAAM,CAAC,YAAY,EACnF,UAAU,SAAS,EACnB,MAAK,eAAoC,KACxC,YAAY,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,CA2PxC,CAAA;AAuCD,eAAO,MAAM,mBAAmB,GAAI,MAAM,MAAM,UAE/C,CAAA;AAED,eAAO,MAAM,eAAe,GAAI,IAAI,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,KAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CA4ClF,CAAA"}
@@ -1,17 +1,20 @@
1
- import { Option, Predicate, Schema } from '@livestore/utils/effect';
2
- import { QueryBuilderAstSymbol, TypeId } from './api.js';
1
+ import { casesHandled, shouldNeverHappen } from '@livestore/utils';
2
+ import { Match, Option, Predicate, Schema } from '@livestore/utils/effect';
3
+ import { QueryBuilderAstSymbol, QueryBuilderTypeId } from './api.js';
4
+ import { astToSql } from './astToSql.js';
3
5
  export const makeQueryBuilder = (tableDef, ast = emptyAst(tableDef)) => {
4
6
  const api = {
5
7
  // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
6
8
  select() {
7
- assertQueryBuilderAst(ast);
9
+ assertSelectQueryBuilderAst(ast);
8
10
  // eslint-disable-next-line prefer-rest-params
9
11
  const params = [...arguments];
10
- if (params.length === 2 && typeof params[0] === 'string' && typeof params[1] === 'object') {
11
- const [col, options] = params;
12
+ // Pluck if there's only one column selected
13
+ if (params.length === 1) {
14
+ const [col] = params;
12
15
  return makeQueryBuilder(tableDef, {
13
16
  ...ast,
14
- resultSchemaSingle: options.pluck ? ast.resultSchemaSingle.pipe(Schema.pluck(col)) : ast.resultSchemaSingle,
17
+ resultSchemaSingle: ast.resultSchemaSingle.pipe(Schema.pluck(col)),
15
18
  select: { columns: [col] },
16
19
  });
17
20
  }
@@ -23,9 +26,11 @@ export const makeQueryBuilder = (tableDef, ast = emptyAst(tableDef)) => {
23
26
  });
24
27
  },
25
28
  // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
26
- where() {
27
- if (isRowQuery(ast))
28
- return invalidQueryBuilder();
29
+ where: function () {
30
+ if (ast._tag === 'InsertQuery')
31
+ return invalidQueryBuilder('Cannot use where with insert');
32
+ if (ast._tag === 'RowQuery')
33
+ return invalidQueryBuilder('Cannot use where with row');
29
34
  if (arguments.length === 1) {
30
35
  // eslint-disable-next-line prefer-rest-params
31
36
  const params = arguments[0];
@@ -34,23 +39,43 @@ export const makeQueryBuilder = (tableDef, ast = emptyAst(tableDef)) => {
34
39
  .map(([col, value]) => Predicate.hasProperty(value, 'op') && Predicate.hasProperty(value, 'value')
35
40
  ? { col, op: value.op, value: value.value }
36
41
  : { col, op: '=', value });
37
- return makeQueryBuilder(tableDef, {
38
- ...ast,
39
- where: [...ast.where, ...newOps],
40
- });
42
+ switch (ast._tag) {
43
+ case 'CountQuery':
44
+ case 'SelectQuery':
45
+ case 'UpdateQuery':
46
+ case 'DeleteQuery': {
47
+ return makeQueryBuilder(tableDef, {
48
+ ...ast,
49
+ where: [...ast.where, ...newOps],
50
+ });
51
+ }
52
+ default: {
53
+ return casesHandled(ast);
54
+ }
55
+ }
41
56
  }
42
57
  // eslint-disable-next-line prefer-rest-params
43
58
  const [col, opOrValue, valueOrUndefined] = arguments;
44
59
  const op = valueOrUndefined === undefined ? '=' : opOrValue;
45
60
  const value = valueOrUndefined === undefined ? opOrValue : valueOrUndefined;
46
- return makeQueryBuilder(tableDef, {
47
- ...ast,
48
- where: [...ast.where, { col, op, value }],
49
- });
61
+ switch (ast._tag) {
62
+ case 'CountQuery':
63
+ case 'SelectQuery':
64
+ case 'UpdateQuery':
65
+ case 'DeleteQuery': {
66
+ return makeQueryBuilder(tableDef, {
67
+ ...ast,
68
+ where: [...ast.where, { col, op, value }],
69
+ });
70
+ }
71
+ default: {
72
+ return casesHandled(ast);
73
+ }
74
+ }
50
75
  },
51
76
  // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
52
77
  orderBy() {
53
- assertQueryBuilderAst(ast);
78
+ assertSelectQueryBuilderAst(ast);
54
79
  if (arguments.length === 0 || arguments.length > 2)
55
80
  return invalidQueryBuilder();
56
81
  if (arguments.length === 1) {
@@ -69,60 +94,108 @@ export const makeQueryBuilder = (tableDef, ast = emptyAst(tableDef)) => {
69
94
  });
70
95
  },
71
96
  limit: (limit) => {
72
- assertQueryBuilderAst(ast);
97
+ assertSelectQueryBuilderAst(ast);
73
98
  return makeQueryBuilder(tableDef, { ...ast, limit: Option.some(limit) });
74
99
  },
75
100
  offset: (offset) => {
76
- assertQueryBuilderAst(ast);
101
+ assertSelectQueryBuilderAst(ast);
77
102
  return makeQueryBuilder(tableDef, { ...ast, offset: Option.some(offset) });
78
103
  },
79
104
  count: () => {
80
105
  if (isRowQuery(ast))
81
106
  return invalidQueryBuilder();
82
107
  return makeQueryBuilder(tableDef, {
83
- ...ast,
84
- resultSchema: Schema.Struct({ count: Schema.Number }).pipe(Schema.pluck('count'), Schema.Array, Schema.headOrElse()),
85
108
  _tag: 'CountQuery',
109
+ tableDef,
110
+ where: [],
111
+ resultSchema: Schema.Struct({ count: Schema.Number }).pipe(Schema.pluck('count'), Schema.Array, Schema.headOrElse()),
86
112
  });
87
113
  },
88
114
  first: (options) => {
89
- assertQueryBuilderAst(ast);
115
+ assertSelectQueryBuilderAst(ast);
90
116
  if (ast.limit._tag === 'Some')
91
117
  return invalidQueryBuilder(`.first() can't be called after .limit()`);
92
118
  return makeQueryBuilder(tableDef, {
93
119
  ...ast,
94
120
  limit: Option.some(1),
95
- // TODO improve
96
- pickFirst: options?.fallback ? { fallback: options.fallback } : { fallback: () => undefined },
121
+ pickFirst: options?.fallback ? { fallback: options.fallback } : 'no-fallback',
97
122
  });
98
123
  },
99
- // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
100
- row() {
101
- // eslint-disable-next-line prefer-rest-params
102
- const params = [...arguments];
103
- let id;
104
- if (tableDef.options.isSingleton) {
105
- id = tableDef.sqliteDef.columns.id.default.pipe(Option.getOrThrow);
106
- }
107
- else {
108
- id = params[0];
109
- if (id === undefined) {
110
- invalidQueryBuilder(`Id missing for row query on non-singleton table ${tableDef.sqliteDef.name}`);
111
- }
112
- }
113
- // TODO validate all required columns are present and values are matching the schema
114
- const insertValues = params[1]?.insertValues ?? {};
124
+ // // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
125
+ // getOrCreate() {
126
+ // if (tableDef.options.isClientDocumentTable === false) {
127
+ // return invalidQueryBuilder(`getOrCreate() is not allowed when table is not a client document table`)
128
+ // }
129
+ // // eslint-disable-next-line prefer-rest-params
130
+ // const params = [...arguments]
131
+ // let id: string | number
132
+ // // TODO refactor to handle default id
133
+ // id = params[0] as string | number
134
+ // if (id === undefined) {
135
+ // invalidQueryBuilder(`Id missing for row query on non-singleton table ${tableDef.sqliteDef.name}`)
136
+ // }
137
+ // // TODO validate all required columns are present and values are matching the schema
138
+ // const insertValues: Record<string, unknown> = params[1]?.insertValues ?? {}
139
+ // return makeQueryBuilder(tableDef, {
140
+ // _tag: 'RowQuery',
141
+ // id,
142
+ // tableDef,
143
+ // insertValues,
144
+ // }) as any
145
+ // },
146
+ insert: (values) => {
147
+ const filteredValues = Object.fromEntries(Object.entries(values).filter(([, value]) => value !== undefined));
148
+ return makeQueryBuilder(tableDef, {
149
+ _tag: 'InsertQuery',
150
+ tableDef,
151
+ values: filteredValues,
152
+ onConflict: undefined,
153
+ returning: undefined,
154
+ resultSchema: Schema.Void,
155
+ });
156
+ },
157
+ onConflict: (targetOrTargets, action, updateValues) => {
158
+ const targets = Array.isArray(targetOrTargets) ? targetOrTargets : [targetOrTargets];
159
+ assertInsertQueryBuilderAst(ast);
160
+ const onConflict = Match.value(action).pipe(Match.when('ignore', () => ({ targets, action: { _tag: 'ignore' } })), Match.when('replace', () => ({ targets, action: { _tag: 'replace' } })), Match.when('update', () => ({ targets, action: { _tag: 'update', update: updateValues } })), Match.exhaustive);
161
+ return makeQueryBuilder(tableDef, {
162
+ ...ast,
163
+ onConflict,
164
+ });
165
+ },
166
+ returning: (...columns) => {
167
+ assertWriteQueryBuilderAst(ast);
115
168
  return makeQueryBuilder(tableDef, {
116
- _tag: 'RowQuery',
117
- id,
169
+ ...ast,
170
+ returning: columns,
171
+ resultSchema: tableDef.rowSchema.pipe(Schema.pick(...columns), Schema.Array),
172
+ });
173
+ },
174
+ update: (values) => {
175
+ const filteredValues = Object.fromEntries(Object.entries(values).filter(([, value]) => value !== undefined));
176
+ return makeQueryBuilder(tableDef, {
177
+ _tag: 'UpdateQuery',
178
+ tableDef,
179
+ values: filteredValues,
180
+ where: [],
181
+ returning: undefined,
182
+ resultSchema: Schema.Void,
183
+ });
184
+ },
185
+ delete: () => {
186
+ return makeQueryBuilder(tableDef, {
187
+ _tag: 'DeleteQuery',
118
188
  tableDef,
119
- insertValues,
189
+ where: [],
190
+ returning: undefined,
191
+ resultSchema: Schema.Void,
120
192
  });
121
193
  },
122
194
  };
123
195
  return {
124
- [TypeId]: TypeId,
196
+ [QueryBuilderTypeId]: QueryBuilderTypeId,
125
197
  [QueryBuilderAstSymbol]: ast,
198
+ ['ResultType']: 'only-for-type-inference',
126
199
  asSql: () => astToSql(ast),
127
200
  toString: () => {
128
201
  try {
@@ -146,98 +219,67 @@ const emptyAst = (tableDef) => ({
146
219
  limit: Option.none(),
147
220
  tableDef,
148
221
  where: [],
149
- resultSchemaSingle: tableDef.schema,
222
+ resultSchemaSingle: tableDef.rowSchema,
150
223
  });
151
- const astToSql = (ast) => {
152
- if (isRowQuery(ast)) {
153
- // TODO
154
- return { query: `SELECT * FROM '${ast.tableDef.sqliteDef.name}' WHERE id = ?`, bindValues: [ast.id] };
224
+ // Helper functions
225
+ // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
226
+ function assertSelectQueryBuilderAst(ast) {
227
+ if (ast._tag !== 'SelectQuery') {
228
+ return shouldNeverHappen('Expected SelectQuery but got ' + ast._tag);
155
229
  }
156
- const bindValues = [];
157
- // TODO bind values
158
- const whereStmt = ast.where.length > 0
159
- ? `WHERE ${ast.where
160
- .map(({ col, op, value }) => {
161
- if (value === null) {
162
- if (op !== '=' && op !== '!=') {
163
- throw new Error(`Unsupported operator for NULL value: ${op}`);
164
- }
165
- const opStmt = op === '=' ? 'IS' : 'IS NOT';
166
- return `${col} ${opStmt} NULL`;
167
- }
168
- else {
169
- const colDef = ast.tableDef.sqliteDef.columns[col];
170
- if (colDef === undefined) {
171
- throw new Error(`Column ${col} not found`);
172
- }
173
- const isArray = op === 'IN' || op === 'NOT IN';
174
- const colSchema = isArray ? Schema.Array(colDef.schema) : colDef.schema;
175
- const encodedValue = Schema.encodeSync(colSchema)(value);
176
- if (isArray) {
177
- bindValues.push(...encodedValue);
178
- const placeholders = Array.from({ length: encodedValue.length }, () => '?').join(', ');
179
- return `${col} ${op} (${placeholders})`;
180
- }
181
- else {
182
- bindValues.push(encodedValue);
183
- return `${col} ${op} ?`;
184
- }
185
- }
186
- })
187
- .join(' AND ')}`
188
- : '';
189
- if (ast._tag === 'CountQuery') {
190
- const selectFromStmt = `SELECT COUNT(*) as count FROM '${ast.tableDef.sqliteDef.name}'`;
191
- const query = [selectFromStmt, whereStmt].filter((_) => _.length > 0).join(' ');
192
- return { query, bindValues };
230
+ }
231
+ // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
232
+ function assertInsertQueryBuilderAst(ast) {
233
+ if (ast._tag !== 'InsertQuery') {
234
+ return shouldNeverHappen('Expected InsertQuery but got ' + ast._tag);
193
235
  }
194
- const columnsStmt = ast.select.columns.length === 0 ? '*' : ast.select.columns.join(', ');
195
- const selectStmt = `SELECT ${columnsStmt}`;
196
- const fromStmt = `FROM '${ast.tableDef.sqliteDef.name}'`;
197
- const orderByStmt = ast.orderBy.length > 0
198
- ? `ORDER BY ${ast.orderBy.map(({ col, direction }) => `${col} ${direction}`).join(', ')}`
199
- : '';
200
- const limitStmt = ast.limit._tag === 'Some' ? `LIMIT ?` : '';
201
- if (ast.limit._tag === 'Some')
202
- bindValues.push(ast.limit.value);
203
- const offsetStmt = ast.offset._tag === 'Some' ? `OFFSET ?` : '';
204
- if (ast.offset._tag === 'Some')
205
- bindValues.push(ast.offset.value);
206
- const query = [selectStmt, fromStmt, whereStmt, orderByStmt, offsetStmt, limitStmt]
207
- .map((_) => _.trim())
208
- .filter((_) => _.length > 0)
209
- .join(' ');
210
- // TODO bind values
211
- return { query, bindValues };
212
- };
236
+ }
213
237
  // eslint-disable-next-line prefer-arrow/prefer-arrow-functions
214
- function assertQueryBuilderAst(ast) {
215
- if (ast._tag !== 'SelectQuery') {
216
- throw new Error('Expected SelectQuery but got ' + ast._tag);
238
+ function assertWriteQueryBuilderAst(ast) {
239
+ if (ast._tag !== 'InsertQuery' && ast._tag !== 'UpdateQuery' && ast._tag !== 'DeleteQuery') {
240
+ return shouldNeverHappen('Expected WriteQuery but got ' + ast._tag);
217
241
  }
218
242
  }
219
243
  const isRowQuery = (ast) => ast._tag === 'RowQuery';
220
244
  export const invalidQueryBuilder = (msg) => {
221
- throw new Error('Invalid query builder' + (msg ? `: ${msg}` : ''));
245
+ return shouldNeverHappen('Invalid query builder' + (msg ? `: ${msg}` : ''));
222
246
  };
223
247
  export const getResultSchema = (qb) => {
224
248
  const queryAst = qb[QueryBuilderAstSymbol];
225
- if (queryAst._tag === 'SelectQuery') {
226
- const arraySchema = Schema.Array(queryAst.resultSchemaSingle);
227
- if (queryAst.pickFirst !== false) {
228
- return arraySchema.pipe(Schema.headOrElse(queryAst.pickFirst.fallback));
249
+ switch (queryAst._tag) {
250
+ case 'SelectQuery': {
251
+ const arraySchema = Schema.Array(queryAst.resultSchemaSingle);
252
+ if (queryAst.pickFirst === false) {
253
+ return arraySchema;
254
+ }
255
+ else if (queryAst.pickFirst === 'no-fallback') {
256
+ // Will throw if the array is empty
257
+ return arraySchema.pipe(Schema.headOrElse());
258
+ }
259
+ else {
260
+ const fallbackValue = queryAst.pickFirst.fallback();
261
+ return Schema.Union(arraySchema, Schema.Tuple(Schema.Literal(fallbackValue))).pipe(Schema.headOrElse(() => fallbackValue));
262
+ }
229
263
  }
230
- return arraySchema;
231
- }
232
- else if (queryAst._tag === 'CountQuery') {
233
- return Schema.Struct({ count: Schema.Number }).pipe(Schema.pluck('count'), Schema.Array, Schema.headOrElse());
234
- }
235
- else {
236
- if (queryAst.tableDef.options.isSingleColumn) {
237
- return queryAst.tableDef.schema.pipe(Schema.pluck('value'), Schema.Array, Schema.headOrElse());
264
+ case 'CountQuery': {
265
+ return Schema.Struct({ count: Schema.Number }).pipe(Schema.pluck('count'), Schema.Array, Schema.headOrElse());
266
+ }
267
+ case 'InsertQuery':
268
+ case 'UpdateQuery':
269
+ case 'DeleteQuery': {
270
+ // For write operations with RETURNING clause, we need to return the appropriate schema
271
+ if (queryAst.returning && queryAst.returning.length > 0) {
272
+ // Create a schema for the returned columns
273
+ return queryAst.tableDef.rowSchema.pipe(Schema.pick(...queryAst.returning), Schema.Array);
274
+ }
275
+ // For write operations without RETURNING, the result is the number of affected rows
276
+ return Schema.Number;
277
+ }
278
+ case 'RowQuery': {
279
+ return queryAst.tableDef.rowSchema.pipe(Schema.pluck('value'), Schema.annotations({ title: `${queryAst.tableDef.sqliteDef.name}.value` }), Schema.Array, Schema.headOrElse());
238
280
  }
239
- else {
240
- return queryAst.tableDef.schema.pipe(Schema.Array, Schema.headOrElse());
281
+ default: {
282
+ casesHandled(queryAst);
241
283
  }
242
284
  }
243
285
  };