@livestore/common 0.3.0-dev.5 → 0.3.0-dev.51

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 (491) 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 +120 -64
  7. package/dist/adapter-types.d.ts.map +1 -1
  8. package/dist/adapter-types.js +39 -8
  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 +390 -0
  16. package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -0
  17. package/dist/devtools/devtools-messages-client-session.js +97 -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 -580
  28. package/dist/devtools/devtools-messages.d.ts.map +1 -1
  29. package/dist/devtools/devtools-messages.js +3 -174
  30. package/dist/devtools/devtools-messages.js.map +1 -1
  31. package/dist/devtools/devtools-sessioninfo.d.ts +32 -0
  32. package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -0
  33. package/dist/devtools/devtools-sessioninfo.js +36 -0
  34. package/dist/devtools/devtools-sessioninfo.js.map +1 -0
  35. package/dist/devtools/mod.d.ts +55 -0
  36. package/dist/devtools/mod.d.ts.map +1 -0
  37. package/dist/devtools/mod.js +33 -0
  38. package/dist/devtools/mod.js.map +1 -0
  39. package/dist/index.d.ts +7 -13
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +7 -9
  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 +595 -0
  46. package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -0
  47. package/dist/leader-thread/connection.d.ts +34 -6
  48. package/dist/leader-thread/connection.d.ts.map +1 -1
  49. package/dist/leader-thread/connection.js +22 -7
  50. package/dist/leader-thread/connection.js.map +1 -1
  51. package/dist/leader-thread/eventlog.d.ts +27 -0
  52. package/dist/leader-thread/eventlog.d.ts.map +1 -0
  53. package/dist/leader-thread/eventlog.js +119 -0
  54. package/dist/leader-thread/eventlog.js.map +1 -0
  55. package/dist/leader-thread/leader-worker-devtools.d.ts +1 -1
  56. package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
  57. package/dist/leader-thread/leader-worker-devtools.js +155 -80
  58. package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
  59. package/dist/leader-thread/make-leader-thread-layer.d.ts +23 -11
  60. package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
  61. package/dist/leader-thread/make-leader-thread-layer.js +72 -47
  62. package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
  63. package/dist/leader-thread/materialize-event.d.ts +16 -0
  64. package/dist/leader-thread/materialize-event.d.ts.map +1 -0
  65. package/dist/leader-thread/materialize-event.js +109 -0
  66. package/dist/leader-thread/materialize-event.js.map +1 -0
  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 +33 -31
  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 +87 -40
  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/make-client-session.d.ts +23 -0
  84. package/dist/make-client-session.d.ts.map +1 -0
  85. package/dist/make-client-session.js +57 -0
  86. package/dist/make-client-session.js.map +1 -0
  87. package/dist/materializer-helper.d.ts +23 -0
  88. package/dist/materializer-helper.d.ts.map +1 -0
  89. package/dist/materializer-helper.js +86 -0
  90. package/dist/materializer-helper.js.map +1 -0
  91. package/dist/otel.d.ts +2 -0
  92. package/dist/otel.d.ts.map +1 -1
  93. package/dist/otel.js +5 -0
  94. package/dist/otel.js.map +1 -1
  95. package/dist/rematerialize-from-eventlog.d.ts +14 -0
  96. package/dist/rematerialize-from-eventlog.d.ts.map +1 -0
  97. package/dist/rematerialize-from-eventlog.js +64 -0
  98. package/dist/rematerialize-from-eventlog.js.map +1 -0
  99. package/dist/schema/EventDef.d.ts +146 -0
  100. package/dist/schema/EventDef.d.ts.map +1 -0
  101. package/dist/schema/EventDef.js +58 -0
  102. package/dist/schema/EventDef.js.map +1 -0
  103. package/dist/schema/EventId.d.ts +43 -25
  104. package/dist/schema/EventId.d.ts.map +1 -1
  105. package/dist/schema/EventId.js +56 -18
  106. package/dist/schema/EventId.js.map +1 -1
  107. package/dist/schema/EventId.test.d.ts +2 -0
  108. package/dist/schema/EventId.test.d.ts.map +1 -0
  109. package/dist/schema/EventId.test.js +11 -0
  110. package/dist/schema/EventId.test.js.map +1 -0
  111. package/dist/schema/EventNumber.d.ts +57 -0
  112. package/dist/schema/EventNumber.d.ts.map +1 -0
  113. package/dist/schema/EventNumber.js +82 -0
  114. package/dist/schema/EventNumber.js.map +1 -0
  115. package/dist/schema/EventNumber.test.d.ts +2 -0
  116. package/dist/schema/EventNumber.test.d.ts.map +1 -0
  117. package/dist/schema/EventNumber.test.js +11 -0
  118. package/dist/schema/EventNumber.test.js.map +1 -0
  119. package/dist/schema/EventSequenceNumber.d.ts +57 -0
  120. package/dist/schema/EventSequenceNumber.d.ts.map +1 -0
  121. package/dist/schema/EventSequenceNumber.js +82 -0
  122. package/dist/schema/EventSequenceNumber.js.map +1 -0
  123. package/dist/schema/EventSequenceNumber.test.d.ts +2 -0
  124. package/dist/schema/EventSequenceNumber.test.d.ts.map +1 -0
  125. package/dist/schema/EventSequenceNumber.test.js +11 -0
  126. package/dist/schema/EventSequenceNumber.test.js.map +1 -0
  127. package/dist/schema/LiveStoreEvent.d.ts +257 -0
  128. package/dist/schema/LiveStoreEvent.d.ts.map +1 -0
  129. package/dist/schema/LiveStoreEvent.js +117 -0
  130. package/dist/schema/LiveStoreEvent.js.map +1 -0
  131. package/dist/schema/events.d.ts +2 -0
  132. package/dist/schema/events.d.ts.map +1 -0
  133. package/dist/schema/events.js +2 -0
  134. package/dist/schema/events.js.map +1 -0
  135. package/dist/schema/mod.d.ts +8 -6
  136. package/dist/schema/mod.d.ts.map +1 -1
  137. package/dist/schema/mod.js +8 -6
  138. package/dist/schema/mod.js.map +1 -1
  139. package/dist/schema/schema.d.ts +50 -32
  140. package/dist/schema/schema.d.ts.map +1 -1
  141. package/dist/schema/schema.js +36 -43
  142. package/dist/schema/schema.js.map +1 -1
  143. package/dist/schema/state/mod.d.ts +3 -0
  144. package/dist/schema/state/mod.d.ts.map +1 -0
  145. package/dist/schema/state/mod.js +3 -0
  146. package/dist/schema/state/mod.js.map +1 -0
  147. package/dist/schema/state/sqlite/client-document-def.d.ts +223 -0
  148. package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -0
  149. package/dist/schema/state/sqlite/client-document-def.js +170 -0
  150. package/dist/schema/state/sqlite/client-document-def.js.map +1 -0
  151. package/dist/schema/state/sqlite/client-document-def.test.d.ts +2 -0
  152. package/dist/schema/state/sqlite/client-document-def.test.d.ts.map +1 -0
  153. package/dist/schema/state/sqlite/client-document-def.test.js +201 -0
  154. package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -0
  155. package/dist/schema/state/sqlite/db-schema/ast/sqlite.d.ts +69 -0
  156. package/dist/schema/state/sqlite/db-schema/ast/sqlite.d.ts.map +1 -0
  157. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js +71 -0
  158. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js.map +1 -0
  159. package/dist/schema/state/sqlite/db-schema/ast/validate.d.ts +3 -0
  160. package/dist/schema/state/sqlite/db-schema/ast/validate.d.ts.map +1 -0
  161. package/dist/schema/state/sqlite/db-schema/ast/validate.js +12 -0
  162. package/dist/schema/state/sqlite/db-schema/ast/validate.js.map +1 -0
  163. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts +90 -0
  164. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts.map +1 -0
  165. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js +87 -0
  166. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js.map +1 -0
  167. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.d.ts +2 -0
  168. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.d.ts.map +1 -0
  169. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js +29 -0
  170. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js.map +1 -0
  171. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts +90 -0
  172. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts.map +1 -0
  173. package/dist/schema/state/sqlite/db-schema/dsl/mod.js +41 -0
  174. package/dist/schema/state/sqlite/db-schema/dsl/mod.js.map +1 -0
  175. package/dist/schema/state/sqlite/db-schema/hash.d.ts +2 -0
  176. package/dist/schema/state/sqlite/db-schema/hash.d.ts.map +1 -0
  177. package/dist/schema/state/sqlite/db-schema/hash.js +14 -0
  178. package/dist/schema/state/sqlite/db-schema/hash.js.map +1 -0
  179. package/dist/schema/state/sqlite/db-schema/mod.d.ts +3 -0
  180. package/dist/schema/state/sqlite/db-schema/mod.d.ts.map +1 -0
  181. package/dist/schema/state/sqlite/db-schema/mod.js +3 -0
  182. package/dist/schema/state/sqlite/db-schema/mod.js.map +1 -0
  183. package/dist/schema/state/sqlite/mod.d.ts +17 -0
  184. package/dist/schema/state/sqlite/mod.d.ts.map +1 -0
  185. package/dist/schema/state/sqlite/mod.js +41 -0
  186. package/dist/schema/state/sqlite/mod.js.map +1 -0
  187. package/dist/schema/state/sqlite/query-builder/api.d.ts +294 -0
  188. package/dist/schema/state/sqlite/query-builder/api.d.ts.map +1 -0
  189. package/dist/schema/state/sqlite/query-builder/api.js +6 -0
  190. package/dist/schema/state/sqlite/query-builder/api.js.map +1 -0
  191. package/dist/schema/state/sqlite/query-builder/astToSql.d.ts +7 -0
  192. package/dist/schema/state/sqlite/query-builder/astToSql.d.ts.map +1 -0
  193. package/dist/schema/state/sqlite/query-builder/astToSql.js +190 -0
  194. package/dist/schema/state/sqlite/query-builder/astToSql.js.map +1 -0
  195. package/dist/schema/state/sqlite/query-builder/impl.d.ts +7 -0
  196. package/dist/schema/state/sqlite/query-builder/impl.d.ts.map +1 -0
  197. package/dist/schema/state/sqlite/query-builder/impl.js +286 -0
  198. package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -0
  199. package/dist/schema/state/sqlite/query-builder/impl.test.d.ts +87 -0
  200. package/dist/schema/state/sqlite/query-builder/impl.test.d.ts.map +1 -0
  201. package/dist/schema/state/sqlite/query-builder/impl.test.js +563 -0
  202. package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -0
  203. package/dist/{query-builder → schema/state/sqlite/query-builder}/mod.d.ts +7 -0
  204. package/dist/schema/state/sqlite/query-builder/mod.d.ts.map +1 -0
  205. package/dist/{query-builder → schema/state/sqlite/query-builder}/mod.js +7 -0
  206. package/dist/schema/state/sqlite/query-builder/mod.js.map +1 -0
  207. package/dist/schema/state/sqlite/schema-helpers.d.ts.map +1 -0
  208. package/dist/schema/{schema-helpers.js → state/sqlite/schema-helpers.js} +1 -1
  209. package/dist/schema/state/sqlite/schema-helpers.js.map +1 -0
  210. package/dist/schema/state/sqlite/system-tables.d.ts +574 -0
  211. package/dist/schema/state/sqlite/system-tables.d.ts.map +1 -0
  212. package/dist/schema/state/sqlite/system-tables.js +88 -0
  213. package/dist/schema/state/sqlite/system-tables.js.map +1 -0
  214. package/dist/schema/state/sqlite/table-def.d.ts +84 -0
  215. package/dist/schema/state/sqlite/table-def.d.ts.map +1 -0
  216. package/dist/schema/state/sqlite/table-def.js +36 -0
  217. package/dist/schema/state/sqlite/table-def.js.map +1 -0
  218. package/dist/schema-management/common.d.ts +7 -7
  219. package/dist/schema-management/common.d.ts.map +1 -1
  220. package/dist/schema-management/common.js.map +1 -1
  221. package/dist/schema-management/migrations.d.ts +6 -6
  222. package/dist/schema-management/migrations.d.ts.map +1 -1
  223. package/dist/schema-management/migrations.js +27 -18
  224. package/dist/schema-management/migrations.js.map +1 -1
  225. package/dist/schema-management/validate-schema.d.ts +8 -0
  226. package/dist/schema-management/validate-schema.d.ts.map +1 -0
  227. package/dist/schema-management/validate-schema.js +39 -0
  228. package/dist/schema-management/validate-schema.js.map +1 -0
  229. package/dist/sql-queries/misc.d.ts.map +1 -1
  230. package/dist/sql-queries/sql-queries.d.ts +1 -1
  231. package/dist/sql-queries/sql-queries.d.ts.map +1 -1
  232. package/dist/sql-queries/sql-queries.js.map +1 -1
  233. package/dist/sql-queries/sql-query-builder.d.ts +1 -1
  234. package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
  235. package/dist/sql-queries/sql-query-builder.js.map +1 -1
  236. package/dist/sql-queries/types.d.ts +2 -1
  237. package/dist/sql-queries/types.d.ts.map +1 -1
  238. package/dist/sql-queries/types.js.map +1 -1
  239. package/dist/sync/ClientSessionSyncProcessor.d.ts +66 -0
  240. package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -0
  241. package/dist/sync/ClientSessionSyncProcessor.js +209 -0
  242. package/dist/sync/ClientSessionSyncProcessor.js.map +1 -0
  243. package/dist/sync/index.d.ts +1 -1
  244. package/dist/sync/index.d.ts.map +1 -1
  245. package/dist/sync/index.js +1 -1
  246. package/dist/sync/index.js.map +1 -1
  247. package/dist/sync/next/compact-events.d.ts.map +1 -1
  248. package/dist/sync/next/compact-events.js +38 -35
  249. package/dist/sync/next/compact-events.js.map +1 -1
  250. package/dist/sync/next/facts.d.ts +21 -21
  251. package/dist/sync/next/facts.d.ts.map +1 -1
  252. package/dist/sync/next/facts.js +11 -11
  253. package/dist/sync/next/facts.js.map +1 -1
  254. package/dist/sync/next/history-dag-common.d.ts +9 -7
  255. package/dist/sync/next/history-dag-common.d.ts.map +1 -1
  256. package/dist/sync/next/history-dag-common.js +10 -5
  257. package/dist/sync/next/history-dag-common.js.map +1 -1
  258. package/dist/sync/next/history-dag.d.ts +0 -2
  259. package/dist/sync/next/history-dag.d.ts.map +1 -1
  260. package/dist/sync/next/history-dag.js +16 -14
  261. package/dist/sync/next/history-dag.js.map +1 -1
  262. package/dist/sync/next/rebase-events.d.ts +10 -8
  263. package/dist/sync/next/rebase-events.d.ts.map +1 -1
  264. package/dist/sync/next/rebase-events.js +18 -10
  265. package/dist/sync/next/rebase-events.js.map +1 -1
  266. package/dist/sync/next/test/compact-events.calculator.test.js +39 -34
  267. package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
  268. package/dist/sync/next/test/compact-events.test.js +77 -77
  269. package/dist/sync/next/test/compact-events.test.js.map +1 -1
  270. package/dist/sync/next/test/{mutation-fixtures.d.ts → event-fixtures.d.ts} +38 -28
  271. package/dist/sync/next/test/event-fixtures.d.ts.map +1 -0
  272. package/dist/sync/next/test/{mutation-fixtures.js → event-fixtures.js} +81 -38
  273. package/dist/sync/next/test/event-fixtures.js.map +1 -0
  274. package/dist/sync/next/test/mod.d.ts +1 -1
  275. package/dist/sync/next/test/mod.d.ts.map +1 -1
  276. package/dist/sync/next/test/mod.js +1 -1
  277. package/dist/sync/next/test/mod.js.map +1 -1
  278. package/dist/sync/sync.d.ts +60 -25
  279. package/dist/sync/sync.d.ts.map +1 -1
  280. package/dist/sync/sync.js +10 -6
  281. package/dist/sync/sync.js.map +1 -1
  282. package/dist/sync/syncstate.d.ts +213 -82
  283. package/dist/sync/syncstate.d.ts.map +1 -1
  284. package/dist/sync/syncstate.js +337 -139
  285. package/dist/sync/syncstate.js.map +1 -1
  286. package/dist/sync/syncstate.test.js +310 -286
  287. package/dist/sync/syncstate.test.js.map +1 -1
  288. package/dist/sync/validate-push-payload.d.ts +2 -2
  289. package/dist/sync/validate-push-payload.d.ts.map +1 -1
  290. package/dist/sync/validate-push-payload.js +4 -4
  291. package/dist/sync/validate-push-payload.js.map +1 -1
  292. package/dist/util.d.ts +2 -2
  293. package/dist/util.d.ts.map +1 -1
  294. package/dist/version.d.ts +2 -2
  295. package/dist/version.d.ts.map +1 -1
  296. package/dist/version.js +2 -2
  297. package/dist/version.js.map +1 -1
  298. package/package.json +13 -6
  299. package/src/__tests__/fixture.ts +36 -15
  300. package/src/adapter-types.ts +107 -68
  301. package/src/debug-info.ts +1 -0
  302. package/src/devtools/devtools-messages-client-session.ts +142 -0
  303. package/src/devtools/devtools-messages-common.ts +115 -0
  304. package/src/devtools/devtools-messages-leader.ts +191 -0
  305. package/src/devtools/devtools-messages.ts +3 -246
  306. package/src/devtools/devtools-sessioninfo.ts +101 -0
  307. package/src/devtools/mod.ts +59 -0
  308. package/src/index.ts +7 -15
  309. package/src/leader-thread/LeaderSyncProcessor.ts +940 -0
  310. package/src/leader-thread/connection.ts +54 -9
  311. package/src/leader-thread/eventlog.ts +199 -0
  312. package/src/leader-thread/leader-worker-devtools.ts +227 -104
  313. package/src/leader-thread/make-leader-thread-layer.ts +128 -78
  314. package/src/leader-thread/materialize-event.ts +173 -0
  315. package/src/leader-thread/mod.ts +1 -1
  316. package/src/leader-thread/recreate-db.ts +38 -39
  317. package/src/leader-thread/shutdown-channel.ts +2 -4
  318. package/src/leader-thread/types.ts +96 -50
  319. package/src/make-client-session.ts +136 -0
  320. package/src/materializer-helper.ts +138 -0
  321. package/src/otel.ts +8 -0
  322. package/src/rematerialize-from-eventlog.ts +117 -0
  323. package/src/schema/EventDef.ts +227 -0
  324. package/src/schema/EventSequenceNumber.test.ts +12 -0
  325. package/src/schema/EventSequenceNumber.ts +121 -0
  326. package/src/schema/LiveStoreEvent.ts +240 -0
  327. package/src/schema/events.ts +1 -0
  328. package/src/schema/mod.ts +8 -6
  329. package/src/schema/schema.ts +88 -84
  330. package/src/schema/state/mod.ts +2 -0
  331. package/src/schema/state/sqlite/client-document-def.test.ts +238 -0
  332. package/src/schema/state/sqlite/client-document-def.ts +444 -0
  333. package/src/schema/state/sqlite/db-schema/ast/sqlite.ts +142 -0
  334. package/src/schema/state/sqlite/db-schema/ast/validate.ts +13 -0
  335. package/src/schema/state/sqlite/db-schema/dsl/__snapshots__/field-defs.test.ts.snap +206 -0
  336. package/src/schema/state/sqlite/db-schema/dsl/field-defs.test.ts +35 -0
  337. package/src/schema/state/sqlite/db-schema/dsl/field-defs.ts +242 -0
  338. package/src/schema/state/sqlite/db-schema/dsl/mod.ts +222 -0
  339. package/src/schema/state/sqlite/db-schema/hash.ts +14 -0
  340. package/src/schema/state/sqlite/db-schema/mod.ts +2 -0
  341. package/src/schema/state/sqlite/mod.ts +73 -0
  342. package/src/schema/state/sqlite/query-builder/api.ts +440 -0
  343. package/src/schema/state/sqlite/query-builder/astToSql.ts +232 -0
  344. package/src/schema/state/sqlite/query-builder/impl.test.ts +617 -0
  345. package/src/schema/state/sqlite/query-builder/impl.ts +351 -0
  346. package/src/{query-builder → schema/state/sqlite/query-builder}/mod.ts +7 -0
  347. package/src/schema/{schema-helpers.ts → state/sqlite/schema-helpers.ts} +1 -1
  348. package/src/schema/state/sqlite/system-tables.ts +117 -0
  349. package/src/schema/state/sqlite/table-def.ts +197 -0
  350. package/src/schema-management/common.ts +7 -7
  351. package/src/schema-management/migrations.ts +37 -31
  352. package/src/schema-management/validate-schema.ts +61 -0
  353. package/src/sql-queries/sql-queries.ts +1 -1
  354. package/src/sql-queries/sql-query-builder.ts +1 -2
  355. package/src/sql-queries/types.ts +3 -1
  356. package/src/sync/ClientSessionSyncProcessor.ts +332 -0
  357. package/src/sync/index.ts +1 -1
  358. package/src/sync/next/compact-events.ts +38 -35
  359. package/src/sync/next/facts.ts +43 -41
  360. package/src/sync/next/history-dag-common.ts +17 -10
  361. package/src/sync/next/history-dag.ts +16 -17
  362. package/src/sync/next/rebase-events.ts +29 -17
  363. package/src/sync/next/test/compact-events.calculator.test.ts +46 -46
  364. package/src/sync/next/test/compact-events.test.ts +79 -79
  365. package/src/sync/next/test/event-fixtures.ts +226 -0
  366. package/src/sync/next/test/mod.ts +1 -1
  367. package/src/sync/sync.ts +60 -24
  368. package/src/sync/syncstate.test.ts +347 -320
  369. package/src/sync/syncstate.ts +422 -230
  370. package/src/sync/validate-push-payload.ts +6 -6
  371. package/src/version.ts +2 -2
  372. package/dist/derived-mutations.d.ts +0 -109
  373. package/dist/derived-mutations.d.ts.map +0 -1
  374. package/dist/derived-mutations.js +0 -54
  375. package/dist/derived-mutations.js.map +0 -1
  376. package/dist/derived-mutations.test.d.ts +0 -2
  377. package/dist/derived-mutations.test.d.ts.map +0 -1
  378. package/dist/derived-mutations.test.js +0 -93
  379. package/dist/derived-mutations.test.js.map +0 -1
  380. package/dist/devtools/devtools-bridge.d.ts +0 -13
  381. package/dist/devtools/devtools-bridge.d.ts.map +0 -1
  382. package/dist/devtools/devtools-bridge.js +0 -2
  383. package/dist/devtools/devtools-bridge.js.map +0 -1
  384. package/dist/devtools/devtools-window-message.d.ts +0 -29
  385. package/dist/devtools/devtools-window-message.d.ts.map +0 -1
  386. package/dist/devtools/devtools-window-message.js +0 -33
  387. package/dist/devtools/devtools-window-message.js.map +0 -1
  388. package/dist/devtools/index.d.ts +0 -42
  389. package/dist/devtools/index.d.ts.map +0 -1
  390. package/dist/devtools/index.js +0 -48
  391. package/dist/devtools/index.js.map +0 -1
  392. package/dist/init-singleton-tables.d.ts +0 -4
  393. package/dist/init-singleton-tables.d.ts.map +0 -1
  394. package/dist/init-singleton-tables.js +0 -16
  395. package/dist/init-singleton-tables.js.map +0 -1
  396. package/dist/leader-thread/apply-mutation.d.ts +0 -8
  397. package/dist/leader-thread/apply-mutation.d.ts.map +0 -1
  398. package/dist/leader-thread/apply-mutation.js +0 -95
  399. package/dist/leader-thread/apply-mutation.js.map +0 -1
  400. package/dist/leader-thread/leader-sync-processor.d.ts +0 -47
  401. package/dist/leader-thread/leader-sync-processor.d.ts.map +0 -1
  402. package/dist/leader-thread/leader-sync-processor.js +0 -425
  403. package/dist/leader-thread/leader-sync-processor.js.map +0 -1
  404. package/dist/leader-thread/mutationlog.d.ts +0 -10
  405. package/dist/leader-thread/mutationlog.d.ts.map +0 -1
  406. package/dist/leader-thread/mutationlog.js +0 -28
  407. package/dist/leader-thread/mutationlog.js.map +0 -1
  408. package/dist/leader-thread/pull-queue-set.d.ts +0 -7
  409. package/dist/leader-thread/pull-queue-set.d.ts.map +0 -1
  410. package/dist/leader-thread/pull-queue-set.js +0 -39
  411. package/dist/leader-thread/pull-queue-set.js.map +0 -1
  412. package/dist/mutation.d.ts +0 -13
  413. package/dist/mutation.d.ts.map +0 -1
  414. package/dist/mutation.js +0 -57
  415. package/dist/mutation.js.map +0 -1
  416. package/dist/query-builder/api.d.ts +0 -190
  417. package/dist/query-builder/api.d.ts.map +0 -1
  418. package/dist/query-builder/api.js +0 -8
  419. package/dist/query-builder/api.js.map +0 -1
  420. package/dist/query-builder/impl.d.ts +0 -12
  421. package/dist/query-builder/impl.d.ts.map +0 -1
  422. package/dist/query-builder/impl.js +0 -244
  423. package/dist/query-builder/impl.js.map +0 -1
  424. package/dist/query-builder/impl.test.d.ts +0 -2
  425. package/dist/query-builder/impl.test.d.ts.map +0 -1
  426. package/dist/query-builder/impl.test.js +0 -212
  427. package/dist/query-builder/impl.test.js.map +0 -1
  428. package/dist/query-builder/mod.d.ts.map +0 -1
  429. package/dist/query-builder/mod.js.map +0 -1
  430. package/dist/query-info.d.ts +0 -38
  431. package/dist/query-info.d.ts.map +0 -1
  432. package/dist/query-info.js +0 -7
  433. package/dist/query-info.js.map +0 -1
  434. package/dist/rehydrate-from-mutationlog.d.ts +0 -14
  435. package/dist/rehydrate-from-mutationlog.d.ts.map +0 -1
  436. package/dist/rehydrate-from-mutationlog.js +0 -72
  437. package/dist/rehydrate-from-mutationlog.js.map +0 -1
  438. package/dist/schema/MutationEvent.d.ts +0 -166
  439. package/dist/schema/MutationEvent.d.ts.map +0 -1
  440. package/dist/schema/MutationEvent.js +0 -72
  441. package/dist/schema/MutationEvent.js.map +0 -1
  442. package/dist/schema/mutations.d.ts +0 -107
  443. package/dist/schema/mutations.d.ts.map +0 -1
  444. package/dist/schema/mutations.js +0 -42
  445. package/dist/schema/mutations.js.map +0 -1
  446. package/dist/schema/schema-helpers.d.ts.map +0 -1
  447. package/dist/schema/schema-helpers.js.map +0 -1
  448. package/dist/schema/system-tables.d.ts +0 -399
  449. package/dist/schema/system-tables.d.ts.map +0 -1
  450. package/dist/schema/system-tables.js +0 -58
  451. package/dist/schema/system-tables.js.map +0 -1
  452. package/dist/schema/table-def.d.ts +0 -156
  453. package/dist/schema/table-def.d.ts.map +0 -1
  454. package/dist/schema/table-def.js +0 -79
  455. package/dist/schema/table-def.js.map +0 -1
  456. package/dist/schema-management/validate-mutation-defs.d.ts +0 -8
  457. package/dist/schema-management/validate-mutation-defs.d.ts.map +0 -1
  458. package/dist/schema-management/validate-mutation-defs.js +0 -39
  459. package/dist/schema-management/validate-mutation-defs.js.map +0 -1
  460. package/dist/sync/client-session-sync-processor.d.ts +0 -45
  461. package/dist/sync/client-session-sync-processor.d.ts.map +0 -1
  462. package/dist/sync/client-session-sync-processor.js +0 -131
  463. package/dist/sync/client-session-sync-processor.js.map +0 -1
  464. package/dist/sync/next/test/mutation-fixtures.d.ts.map +0 -1
  465. package/dist/sync/next/test/mutation-fixtures.js.map +0 -1
  466. package/src/derived-mutations.test.ts +0 -101
  467. package/src/derived-mutations.ts +0 -166
  468. package/src/devtools/devtools-bridge.ts +0 -14
  469. package/src/devtools/devtools-window-message.ts +0 -27
  470. package/src/devtools/index.ts +0 -48
  471. package/src/init-singleton-tables.ts +0 -24
  472. package/src/leader-thread/apply-mutation.ts +0 -143
  473. package/src/leader-thread/leader-sync-processor.ts +0 -670
  474. package/src/leader-thread/mutationlog.ts +0 -46
  475. package/src/leader-thread/pull-queue-set.ts +0 -58
  476. package/src/mutation.ts +0 -81
  477. package/src/query-builder/api.ts +0 -289
  478. package/src/query-builder/impl.test.ts +0 -239
  479. package/src/query-builder/impl.ts +0 -285
  480. package/src/query-info.ts +0 -78
  481. package/src/rehydrate-from-mutationlog.ts +0 -127
  482. package/src/schema/EventId.ts +0 -60
  483. package/src/schema/MutationEvent.ts +0 -180
  484. package/src/schema/mutations.ts +0 -192
  485. package/src/schema/system-tables.ts +0 -104
  486. package/src/schema/table-def.ts +0 -343
  487. package/src/schema-management/validate-mutation-defs.ts +0 -63
  488. package/src/sync/client-session-sync-processor.ts +0 -207
  489. package/src/sync/next/test/mutation-fixtures.ts +0 -224
  490. package/tsconfig.json +0 -11
  491. /package/dist/schema/{schema-helpers.d.ts → state/sqlite/schema-helpers.d.ts} +0 -0
@@ -1,78 +1,141 @@
1
- import type { HttpClient, Scope } from '@livestore/utils/effect'
1
+ import type { HttpClient, Schema, Scope } from '@livestore/utils/effect'
2
2
  import { Deferred, Effect, Layer, Queue, SubscriptionRef } from '@livestore/utils/effect'
3
3
 
4
- import type { BootStatus, MakeSynchronousDatabase, SqliteError, SynchronousDatabase } from '../adapter-types.js'
4
+ import type { BootStatus, MakeSqliteDb, SqliteError } from '../adapter-types.js'
5
5
  import { UnexpectedError } from '../adapter-types.js'
6
- import type * as Devtools from '../devtools/index.js'
6
+ import type * as Devtools from '../devtools/mod.js'
7
7
  import type { LiveStoreSchema } from '../schema/mod.js'
8
- import { EventId, MutationEvent, mutationLogMetaTable, SYNC_STATUS_TABLE, syncStatusTable } from '../schema/mod.js'
9
- import { migrateTable } from '../schema-management/migrations.js'
10
- import type { InvalidPullError, IsOfflineError, SyncBackend } from '../sync/sync.js'
8
+ import { LiveStoreEvent } from '../schema/mod.js'
9
+ import type { InvalidPullError, IsOfflineError, SyncOptions } from '../sync/sync.js'
11
10
  import { sql } from '../util.js'
12
- import { execSql } from './connection.js'
13
- import { makeLeaderSyncProcessor } from './leader-sync-processor.js'
11
+ import * as Eventlog from './eventlog.js'
14
12
  import { bootDevtools } from './leader-worker-devtools.js'
15
- import { makePullQueueSet } from './pull-queue-set.js'
13
+ import { makeLeaderSyncProcessor } from './LeaderSyncProcessor.js'
14
+ import { makeMaterializeEvent } from './materialize-event.js'
16
15
  import { recreateDb } from './recreate-db.js'
17
16
  import type { ShutdownChannel } from './shutdown-channel.js'
18
- import type { DevtoolsOptions, InitialBlockingSyncContext, InitialSyncOptions, ShutdownState } from './types.js'
17
+ import type {
18
+ DevtoolsOptions,
19
+ InitialBlockingSyncContext,
20
+ InitialSyncOptions,
21
+ LeaderSqliteDb,
22
+ ShutdownState,
23
+ } from './types.js'
19
24
  import { LeaderThreadCtx } from './types.js'
20
25
 
26
+ export interface MakeLeaderThreadLayerParams {
27
+ storeId: string
28
+ syncPayload: Schema.JsonValue | undefined
29
+ clientId: string
30
+ schema: LiveStoreSchema
31
+ makeSqliteDb: MakeSqliteDb
32
+ syncOptions: SyncOptions | undefined
33
+ dbState: LeaderSqliteDb
34
+ dbEventlog: LeaderSqliteDb
35
+ devtoolsOptions: DevtoolsOptions
36
+ shutdownChannel: ShutdownChannel
37
+ params?: {
38
+ localPushBatchSize?: number
39
+ backendPushBatchSize?: number
40
+ }
41
+ testing?: {
42
+ syncProcessor?: {
43
+ delays?: {
44
+ localPushProcessing?: Effect.Effect<void>
45
+ }
46
+ }
47
+ }
48
+ }
49
+
21
50
  export const makeLeaderThreadLayer = ({
22
51
  schema,
23
52
  storeId,
24
53
  clientId,
25
- makeSyncDb,
26
- makeSyncBackend,
27
- db,
28
- dbLog,
54
+ syncPayload,
55
+ makeSqliteDb,
56
+ syncOptions,
57
+ dbState,
58
+ dbEventlog,
29
59
  devtoolsOptions,
30
- initialSyncOptions = { _tag: 'Skip' },
31
60
  shutdownChannel,
32
- }: {
33
- storeId: string
34
- clientId: string
35
- schema: LiveStoreSchema
36
- makeSyncDb: MakeSynchronousDatabase
37
- makeSyncBackend: Effect.Effect<SyncBackend, UnexpectedError, Scope.Scope> | undefined
38
- db: SynchronousDatabase
39
- dbLog: SynchronousDatabase
40
- devtoolsOptions: DevtoolsOptions
41
- initialSyncOptions: InitialSyncOptions | undefined
42
- shutdownChannel: ShutdownChannel
43
- }): Layer.Layer<LeaderThreadCtx, UnexpectedError, Scope.Scope | HttpClient.HttpClient> =>
61
+ params,
62
+ testing,
63
+ }: MakeLeaderThreadLayerParams): Layer.Layer<LeaderThreadCtx, UnexpectedError, Scope.Scope | HttpClient.HttpClient> =>
44
64
  Effect.gen(function* () {
45
65
  const bootStatusQueue = yield* Queue.unbounded<BootStatus>().pipe(Effect.acquireRelease(Queue.shutdown))
46
66
 
47
67
  // TODO do more validation here than just checking the count of tables
48
68
  // Either happens on initial boot or if schema changes
49
- const dbMissing = db.select<{ count: number }>(sql`select count(*) as count from sqlite_master`)[0]!.count === 0
69
+ const dbEventlogMissing =
70
+ dbEventlog.select<{ count: number }>(sql`select count(*) as count from sqlite_master`)[0]!.count === 0
71
+
72
+ const dbStateMissing =
73
+ dbState.select<{ count: number }>(sql`select count(*) as count from sqlite_master`)[0]!.count === 0
50
74
 
51
- const syncBackend = makeSyncBackend === undefined ? undefined : yield* makeSyncBackend
75
+ const syncBackend =
76
+ syncOptions?.backend === undefined
77
+ ? undefined
78
+ : yield* syncOptions.backend({ storeId, clientId, payload: syncPayload })
79
+
80
+ if (syncBackend !== undefined) {
81
+ // We're already connecting to the sync backend concurrently
82
+ yield* syncBackend.connect.pipe(Effect.tapCauseLogPretty, Effect.forkScoped)
83
+ }
52
84
 
53
- const initialBlockingSyncContext = yield* makeInitialBlockingSyncContext({ initialSyncOptions, bootStatusQueue })
85
+ const initialBlockingSyncContext = yield* makeInitialBlockingSyncContext({
86
+ initialSyncOptions: syncOptions?.initialSyncOptions ?? { _tag: 'Skip' },
87
+ bootStatusQueue,
88
+ })
54
89
 
55
- const syncProcessor = yield* makeLeaderSyncProcessor({ schema, dbMissing, dbLog, initialBlockingSyncContext })
90
+ const syncProcessor = yield* makeLeaderSyncProcessor({
91
+ schema,
92
+ dbEventlogMissing,
93
+ dbEventlog,
94
+ dbState,
95
+ dbStateMissing,
96
+ initialBlockingSyncContext,
97
+ onError: syncOptions?.onSyncError ?? 'ignore',
98
+ params: {
99
+ localPushBatchSize: params?.localPushBatchSize,
100
+ backendPushBatchSize: params?.backendPushBatchSize,
101
+ },
102
+ testing: {
103
+ delays: testing?.syncProcessor?.delays,
104
+ },
105
+ })
56
106
 
57
- const extraIncomingMessagesQueue = yield* Queue.unbounded<Devtools.MessageToAppLeader>().pipe(
107
+ const extraIncomingMessagesQueue = yield* Queue.unbounded<Devtools.Leader.MessageToApp>().pipe(
58
108
  Effect.acquireRelease(Queue.shutdown),
59
109
  )
60
110
 
111
+ const devtoolsContext = devtoolsOptions.enabled
112
+ ? {
113
+ enabled: true as const,
114
+ syncBackendLatch: yield* Effect.makeLatch(true),
115
+ syncBackendLatchState: yield* SubscriptionRef.make<{ latchClosed: boolean }>({ latchClosed: false }),
116
+ }
117
+ : { enabled: false as const }
118
+
119
+ const materializeEvent = yield* makeMaterializeEvent({ schema, dbState, dbEventlog })
120
+
61
121
  const ctx = {
62
122
  schema,
63
123
  bootStatusQueue,
64
124
  storeId,
65
125
  clientId,
66
- db,
67
- dbLog,
68
- makeSyncDb,
69
- mutationEventSchema: MutationEvent.makeMutationEventSchema(schema),
126
+ dbState,
127
+ dbEventlog,
128
+ makeSqliteDb,
129
+ eventSchema: LiveStoreEvent.makeEventDefSchema(schema),
70
130
  shutdownStateSubRef: yield* SubscriptionRef.make<ShutdownState>('running'),
71
131
  shutdownChannel,
72
132
  syncBackend,
73
133
  syncProcessor,
74
- connectedClientSessionPullQueues: yield* makePullQueueSet,
134
+ materializeEvent,
75
135
  extraIncomingMessagesQueue,
136
+ devtools: devtoolsContext,
137
+ // State will be set during `bootLeaderThread`
138
+ initialState: {} as any as LeaderThreadCtx['Type']['initialState'],
76
139
  } satisfies typeof LeaderThreadCtx.Service
77
140
 
78
141
  // @ts-expect-error For debugging purposes
@@ -80,13 +143,18 @@ export const makeLeaderThreadLayer = ({
80
143
 
81
144
  const layer = Layer.succeed(LeaderThreadCtx, ctx)
82
145
 
83
- yield* bootLeaderThread({ dbMissing, initialBlockingSyncContext, devtoolsOptions }).pipe(Effect.provide(layer))
146
+ ctx.initialState = yield* bootLeaderThread({
147
+ dbStateMissing,
148
+ initialBlockingSyncContext,
149
+ devtoolsOptions,
150
+ }).pipe(Effect.provide(layer))
84
151
 
85
152
  return layer
86
153
  }).pipe(
87
154
  Effect.withSpan('@livestore/common:leader-thread:boot'),
88
155
  Effect.withSpanScoped('@livestore/common:leader-thread'),
89
156
  UnexpectedError.mapToUnexpectedError,
157
+ Effect.tapCauseLogPretty,
90
158
  Layer.unwrapScoped,
91
159
  )
92
160
 
@@ -100,7 +168,7 @@ const makeInitialBlockingSyncContext = ({
100
168
  Effect.gen(function* () {
101
169
  const ctx = {
102
170
  isDone: false,
103
- processedMutations: 0,
171
+ processedEvents: 0,
104
172
  total: -1,
105
173
  }
106
174
 
@@ -123,10 +191,10 @@ const makeInitialBlockingSyncContext = ({
123
191
  ctx.total = remaining + processed
124
192
  }
125
193
 
126
- ctx.processedMutations += processed
194
+ ctx.processedEvents += processed
127
195
  yield* Queue.offer(bootStatusQueue, {
128
196
  stage: 'syncing',
129
- progress: { done: ctx.processedMutations, total: ctx.total },
197
+ progress: { done: ctx.processedEvents, total: ctx.total },
130
198
  })
131
199
 
132
200
  if (remaining === 0 && blockingDeferred !== undefined) {
@@ -142,61 +210,43 @@ const makeInitialBlockingSyncContext = ({
142
210
  * It also starts various background processes (e.g. syncing)
143
211
  */
144
212
  const bootLeaderThread = ({
145
- dbMissing,
213
+ dbStateMissing,
146
214
  initialBlockingSyncContext,
147
215
  devtoolsOptions,
148
216
  }: {
149
- dbMissing: boolean
217
+ dbStateMissing: boolean
150
218
  initialBlockingSyncContext: InitialBlockingSyncContext
151
219
  devtoolsOptions: DevtoolsOptions
152
220
  }): Effect.Effect<
153
- void,
221
+ LeaderThreadCtx['Type']['initialState'],
154
222
  UnexpectedError | SqliteError | IsOfflineError | InvalidPullError,
155
223
  LeaderThreadCtx | Scope.Scope | HttpClient.HttpClient
156
224
  > =>
157
225
  Effect.gen(function* () {
158
- const { dbLog, bootStatusQueue, syncProcessor } = yield* LeaderThreadCtx
159
-
160
- yield* migrateTable({
161
- db: dbLog,
162
- behaviour: 'create-if-not-exists',
163
- tableAst: mutationLogMetaTable.sqliteDef.ast,
164
- skipMetaTable: true,
165
- })
226
+ const { dbEventlog, bootStatusQueue, syncProcessor } = yield* LeaderThreadCtx
166
227
 
167
- yield* migrateTable({
168
- db: dbLog,
169
- behaviour: 'create-if-not-exists',
170
- tableAst: syncStatusTable.sqliteDef.ast,
171
- skipMetaTable: true,
172
- })
173
-
174
- // Create sync status row if it doesn't exist
175
- yield* execSql(
176
- dbLog,
177
- sql`INSERT INTO ${SYNC_STATUS_TABLE} (head)
178
- SELECT ${EventId.ROOT.global}
179
- WHERE NOT EXISTS (SELECT 1 FROM ${SYNC_STATUS_TABLE})`,
180
- {},
181
- )
182
-
183
- const dbReady = yield* Deferred.make<void>()
228
+ yield* Eventlog.initEventlogDb(dbEventlog)
184
229
 
185
- // We're already starting pulling from the sync backend concurrently but wait until the db is ready before
186
- // processing any incoming mutations
187
- yield* syncProcessor.boot({ dbReady })
230
+ const { migrationsReport } = dbStateMissing ? yield* recreateDb : { migrationsReport: { migrations: [] } }
188
231
 
189
- if (dbMissing) {
190
- yield* recreateDb
191
- }
192
-
193
- yield* Deferred.succeed(dbReady, void 0)
232
+ // NOTE the sync processor depends on the dbs being initialized properly
233
+ const { initialLeaderHead } = yield* syncProcessor.boot
194
234
 
195
235
  if (initialBlockingSyncContext.blockingDeferred !== undefined) {
196
- yield* initialBlockingSyncContext.blockingDeferred
236
+ // Provides a syncing status right away before the first pull response comes in
237
+ yield* Queue.offer(bootStatusQueue, {
238
+ stage: 'syncing',
239
+ progress: { done: 0, total: -1 },
240
+ })
241
+
242
+ yield* initialBlockingSyncContext.blockingDeferred.pipe(
243
+ Effect.withSpan('@livestore/common:leader-thread:initial-sync-blocking'),
244
+ )
197
245
  }
198
246
 
199
247
  yield* Queue.offer(bootStatusQueue, { stage: 'done' })
200
248
 
201
249
  yield* bootDevtools(devtoolsOptions).pipe(Effect.tapCauseLogPretty, Effect.forkScoped)
250
+
251
+ return { migrationsReport, leaderHead: initialLeaderHead }
202
252
  })
@@ -0,0 +1,173 @@
1
+ import { LS_DEV, shouldNeverHappen } from '@livestore/utils'
2
+ import { Effect, ReadonlyArray, Schema } from '@livestore/utils/effect'
3
+
4
+ import type { SqliteDb } from '../adapter-types.js'
5
+ import { getExecArgsFromEvent } from '../materializer-helper.js'
6
+ import type { LiveStoreSchema } from '../schema/mod.js'
7
+ import { EventSequenceNumber, getEventDef, SystemTables } from '../schema/mod.js'
8
+ import { insertRow } from '../sql-queries/index.js'
9
+ import { sql } from '../util.js'
10
+ import { execSql, execSqlPrepared } from './connection.js'
11
+ import * as Eventlog from './eventlog.js'
12
+ import type { MaterializeEvent } from './types.js'
13
+
14
+ export const makeMaterializeEvent = ({
15
+ schema,
16
+ dbState: db,
17
+ dbEventlog,
18
+ }: {
19
+ schema: LiveStoreSchema
20
+ dbState: SqliteDb
21
+ dbEventlog: SqliteDb
22
+ }): Effect.Effect<MaterializeEvent, never> =>
23
+ Effect.gen(function* () {
24
+ const eventDefSchemaHashMap = new Map(
25
+ // TODO Running `Schema.hash` can be a bottleneck for larger schemas. There is an opportunity to run this
26
+ // at build time and lookup the pre-computed hash at runtime.
27
+ // Also see https://github.com/Effect-TS/effect/issues/2719
28
+ [...schema.eventsDefsMap.entries()].map(([k, v]) => [k, Schema.hash(v.schema)] as const),
29
+ )
30
+
31
+ return (eventEncoded, options) =>
32
+ Effect.gen(function* () {
33
+ const skipEventlog = options?.skipEventlog ?? false
34
+
35
+ const eventName = eventEncoded.name
36
+ const { eventDef, materializer } = getEventDef(schema, eventName)
37
+
38
+ const execArgsArr = getExecArgsFromEvent({
39
+ eventDef,
40
+ materializer,
41
+ db,
42
+ event: { decoded: undefined, encoded: eventEncoded },
43
+ })
44
+
45
+ // NOTE we might want to bring this back if we want to debug no-op events
46
+ // const makeExecuteOptions = (statementSql: string, bindValues: any) => ({
47
+ // onRowsChanged: (rowsChanged: number) => {
48
+ // if (rowsChanged === 0) {
49
+ // console.warn(`Event "${eventDef.name}" did not affect any rows:`, statementSql, bindValues)
50
+ // }
51
+ // },
52
+ // })
53
+
54
+ // console.group('[@livestore/common:leader-thread:materializeEvent]', { eventName })
55
+
56
+ const session = db.session()
57
+
58
+ for (const { statementSql, bindValues } of execArgsArr) {
59
+ // console.debug(eventName, statementSql, bindValues)
60
+ // TODO use cached prepared statements instead of exec
61
+ yield* execSqlPrepared(db, statementSql, bindValues)
62
+ }
63
+
64
+ const changeset = session.changeset()
65
+ session.finish()
66
+
67
+ // TODO use prepared statements
68
+ yield* execSql(
69
+ db,
70
+ ...insertRow({
71
+ tableName: SystemTables.SESSION_CHANGESET_META_TABLE,
72
+ columns: SystemTables.sessionChangesetMetaTable.sqliteDef.columns,
73
+ values: {
74
+ seqNumGlobal: eventEncoded.seqNum.global,
75
+ seqNumClient: eventEncoded.seqNum.client,
76
+ // NOTE the changeset will be empty (i.e. null) for no-op events
77
+ changeset: changeset ?? null,
78
+ debug: LS_DEV ? execArgsArr : null,
79
+ },
80
+ }),
81
+ )
82
+
83
+ // console.groupEnd()
84
+
85
+ // write to eventlog
86
+ if (skipEventlog === false) {
87
+ const eventName = eventEncoded.name
88
+ const eventDefSchemaHash =
89
+ eventDefSchemaHashMap.get(eventName) ?? shouldNeverHappen(`Unknown event definition: ${eventName}`)
90
+
91
+ yield* Eventlog.insertIntoEventlog(
92
+ eventEncoded,
93
+ dbEventlog,
94
+ eventDefSchemaHash,
95
+ eventEncoded.clientId,
96
+ eventEncoded.sessionId,
97
+ )
98
+ } else {
99
+ // console.debug('[@livestore/common:leader-thread] skipping eventlog write', mutation, statementSql, bindValues)
100
+ }
101
+
102
+ return {
103
+ sessionChangeset: changeset
104
+ ? {
105
+ _tag: 'sessionChangeset' as const,
106
+ data: changeset,
107
+ debug: LS_DEV ? execArgsArr : null,
108
+ }
109
+ : { _tag: 'no-op' as const },
110
+ }
111
+ }).pipe(
112
+ Effect.withSpan(`@livestore/common:leader-thread:materializeEvent`, {
113
+ attributes: {
114
+ eventName: eventEncoded.name,
115
+ eventNum: eventEncoded.seqNum,
116
+ 'span.label': `${EventSequenceNumber.toString(eventEncoded.seqNum)} ${eventEncoded.name}`,
117
+ },
118
+ }),
119
+ // Effect.logDuration('@livestore/common:leader-thread:materializeEvent'),
120
+ )
121
+ })
122
+
123
+ export const rollback = ({
124
+ dbState,
125
+ dbEventlog,
126
+ eventNumsToRollback,
127
+ }: {
128
+ dbState: SqliteDb
129
+ dbEventlog: SqliteDb
130
+ eventNumsToRollback: EventSequenceNumber.EventSequenceNumber[]
131
+ }) =>
132
+ Effect.gen(function* () {
133
+ const rollbackEvents = dbState
134
+ .select<SystemTables.SessionChangesetMetaRow>(
135
+ sql`SELECT * FROM ${SystemTables.SESSION_CHANGESET_META_TABLE} WHERE (seqNumGlobal, seqNumClient) IN (${eventNumsToRollback.map((id) => `(${id.global}, ${id.client})`).join(', ')})`,
136
+ )
137
+ .map((_) => ({
138
+ seqNum: { global: _.seqNumGlobal, client: _.seqNumClient },
139
+ changeset: _.changeset,
140
+ debug: _.debug,
141
+ }))
142
+ .toSorted((a, b) => EventSequenceNumber.compare(a.seqNum, b.seqNum))
143
+
144
+ // Apply changesets in reverse order
145
+ for (let i = rollbackEvents.length - 1; i >= 0; i--) {
146
+ const { changeset } = rollbackEvents[i]!
147
+ if (changeset !== null) {
148
+ dbState.makeChangeset(changeset).invert().apply()
149
+ }
150
+ }
151
+
152
+ const eventNumPairChunks = ReadonlyArray.chunksOf(100)(
153
+ eventNumsToRollback.map((seqNum) => `(${seqNum.global}, ${seqNum.client})`),
154
+ )
155
+
156
+ // Delete the changeset rows
157
+ for (const eventNumPairChunk of eventNumPairChunks) {
158
+ dbState.execute(
159
+ sql`DELETE FROM ${SystemTables.SESSION_CHANGESET_META_TABLE} WHERE (seqNumGlobal, seqNumClient) IN (${eventNumPairChunk.join(', ')})`,
160
+ )
161
+ }
162
+
163
+ // Delete the eventlog rows
164
+ for (const eventNumPairChunk of eventNumPairChunks) {
165
+ dbEventlog.execute(
166
+ sql`DELETE FROM ${SystemTables.EVENTLOG_META_TABLE} WHERE (seqNumGlobal, seqNumClient) IN (${eventNumPairChunk.join(', ')})`,
167
+ )
168
+ }
169
+ }).pipe(
170
+ Effect.withSpan('@livestore/common:LeaderSyncProcessor:rollback', {
171
+ attributes: { count: eventNumsToRollback.length },
172
+ }),
173
+ )
@@ -3,4 +3,4 @@ export * from './types.js'
3
3
  export * as ShutdownChannel from './shutdown-channel.js'
4
4
  export * from './leader-worker-devtools.js'
5
5
  export * from './make-leader-thread-layer.js'
6
- export * from './mutationlog.js'
6
+ export * as Eventlog from './eventlog.js'
@@ -2,85 +2,80 @@ import { casesHandled } from '@livestore/utils'
2
2
  import type { HttpClient } from '@livestore/utils/effect'
3
3
  import { Effect, Queue } from '@livestore/utils/effect'
4
4
 
5
- import type { InvalidPullError, IsOfflineError, MigrationHooks, SqliteError } from '../index.js'
6
- import { initializeSingletonTables, migrateDb, rehydrateFromMutationLog, UnexpectedError } from '../index.js'
5
+ import type { InvalidPullError, IsOfflineError, MigrationHooks, MigrationsReport, SqliteError } from '../index.js'
6
+ import { migrateDb, rematerializeFromEventlog, UnexpectedError } from '../index.js'
7
7
  import { configureConnection } from './connection.js'
8
8
  import { LeaderThreadCtx } from './types.js'
9
9
 
10
10
  export const recreateDb: Effect.Effect<
11
- void,
11
+ { migrationsReport: MigrationsReport },
12
12
  UnexpectedError | SqliteError | IsOfflineError | InvalidPullError,
13
13
  LeaderThreadCtx | HttpClient.HttpClient
14
14
  > = Effect.gen(function* () {
15
- const { db, dbLog, makeSyncDb, schema, bootStatusQueue } = yield* LeaderThreadCtx
15
+ const { dbState, dbEventlog, schema, bootStatusQueue, materializeEvent } = yield* LeaderThreadCtx
16
16
 
17
- const migrationOptions = schema.migrationOptions
17
+ const migrationOptions = schema.state.sqlite.migrations
18
+ let migrationsReport: MigrationsReport
18
19
 
19
20
  yield* Effect.addFinalizer(
20
21
  Effect.fn('recreateDb:finalizer')(function* (ex) {
21
- if (ex._tag === 'Failure') db.destroy()
22
+ if (ex._tag === 'Failure') dbState.destroy()
22
23
  }),
23
24
  )
24
25
 
25
26
  // NOTE to speed up the operations below, we're creating a temporary in-memory database
26
27
  // and later we'll overwrite the persisted database with the new data
27
- const tmpSyncDb = yield* makeSyncDb({ _tag: 'in-memory' })
28
- yield* configureConnection(tmpSyncDb, { fkEnabled: true })
28
+ // TODO bring back this optimization
29
+ // const tmpDb = yield* makeSqliteDb({ _tag: 'in-memory' })
30
+ const tmpDb = dbState
31
+ yield* configureConnection(tmpDb, { foreignKeys: true })
29
32
 
30
33
  const initDb = (hooks: Partial<MigrationHooks> | undefined) =>
31
34
  Effect.gen(function* () {
32
- yield* Effect.tryAll(() => hooks?.init?.(tmpSyncDb)).pipe(UnexpectedError.mapToUnexpectedError)
35
+ yield* Effect.tryAll(() => hooks?.init?.(tmpDb)).pipe(UnexpectedError.mapToUnexpectedError)
33
36
 
34
- yield* migrateDb({
35
- db: tmpSyncDb,
37
+ const migrationsReport = yield* migrateDb({
38
+ db: tmpDb,
36
39
  schema,
37
40
  onProgress: ({ done, total }) =>
38
41
  Queue.offer(bootStatusQueue, { stage: 'migrating', progress: { done, total } }),
39
42
  })
40
43
 
41
- initializeSingletonTables(schema, tmpSyncDb)
44
+ yield* Effect.tryAll(() => hooks?.pre?.(tmpDb)).pipe(UnexpectedError.mapToUnexpectedError)
42
45
 
43
- yield* Effect.tryAll(() => hooks?.pre?.(tmpSyncDb)).pipe(UnexpectedError.mapToUnexpectedError)
44
-
45
- return tmpSyncDb
46
+ return { migrationsReport, tmpDb }
46
47
  })
47
48
 
48
49
  switch (migrationOptions.strategy) {
49
- case 'from-mutation-log': {
50
+ case 'auto': {
50
51
  const hooks = migrationOptions.hooks
51
- const tmpSyncDb = yield* initDb(hooks)
52
+ const initResult = yield* initDb(hooks)
53
+
54
+ migrationsReport = initResult.migrationsReport
52
55
 
53
- yield* rehydrateFromMutationLog({
54
- db: tmpSyncDb,
55
- logDb: dbLog,
56
+ yield* rematerializeFromEventlog({
57
+ // db: initResult.tmpDb,
58
+ dbEventlog,
56
59
  schema,
57
- migrationOptions,
60
+ materializeEvent,
58
61
  onProgress: ({ done, total }) =>
59
62
  Queue.offer(bootStatusQueue, { stage: 'rehydrating', progress: { done, total } }),
60
63
  })
61
64
 
62
- yield* Effect.tryAll(() => hooks?.post?.(tmpSyncDb)).pipe(UnexpectedError.mapToUnexpectedError)
63
-
64
- break
65
- }
66
- case 'hard-reset': {
67
- const hooks = migrationOptions.hooks
68
- const tmpInMemoryDb = yield* initDb(hooks)
69
-
70
- // The database is migrated but empty now, so nothing else to do
71
-
72
- yield* Effect.tryAll(() => hooks?.post?.(tmpInMemoryDb)).pipe(UnexpectedError.mapToUnexpectedError)
65
+ yield* Effect.tryAll(() => hooks?.post?.(initResult.tmpDb)).pipe(UnexpectedError.mapToUnexpectedError)
73
66
 
74
67
  break
75
68
  }
76
69
  case 'manual': {
77
- const oldDbData = db.export()
70
+ const oldDbData = dbState.export()
71
+
72
+ migrationsReport = { migrations: [] }
78
73
 
79
74
  const newDbData = yield* Effect.tryAll(() => migrationOptions.migrate(oldDbData)).pipe(
80
75
  UnexpectedError.mapToUnexpectedError,
81
76
  )
82
77
 
83
- tmpSyncDb.import(newDbData)
78
+ tmpDb.import(newDbData)
84
79
 
85
80
  // TODO validate schema
86
81
 
@@ -91,17 +86,21 @@ export const recreateDb: Effect.Effect<
91
86
  }
92
87
  }
93
88
 
89
+ // TODO bring back
94
90
  // Import the temporary in-memory database into the persistent database
95
- yield* Effect.sync(() => db.import(tmpSyncDb)).pipe(
96
- Effect.withSpan('@livestore/common:leader-thread:recreateDb:import'),
97
- )
91
+ // yield* Effect.sync(() => db.import(tmpDb)).pipe(
92
+ // Effect.withSpan('@livestore/common:leader-thread:recreateDb:import'),
93
+ // )
98
94
 
99
95
  // TODO maybe bring back re-using this initial snapshot to avoid calling `.export()` again
100
96
  // We've disabled this for now as it made the code too complex, as we often run syncing right after
101
97
  // so the snapshot is no longer up to date
102
- // const snapshotFromTmpDb = tmpSyncDb.export()
98
+ // const snapshotFromTmpDb = tmpDb.export()
99
+
100
+ // TODO bring back
101
+ // tmpDb.close()
103
102
 
104
- tmpSyncDb.close()
103
+ return { migrationsReport }
105
104
  }).pipe(
106
105
  Effect.scoped, // NOTE we're closing the scope here so finalizers are called when the effect is done
107
106
  Effect.withSpan('@livestore/common:leader-thread:recreateDb'),
@@ -1,11 +1,9 @@
1
1
  import type { WebChannel } from '@livestore/utils/effect'
2
2
  import { Schema } from '@livestore/utils/effect'
3
3
 
4
- import { IntentionalShutdownCause } from '../index.js'
4
+ import { IntentionalShutdownCause, UnexpectedError } from '../index.js'
5
5
 
6
- export class DedicatedWorkerDisconnectBroadcast extends Schema.TaggedStruct('DedicatedWorkerDisconnectBroadcast', {}) {}
7
-
8
- export class All extends Schema.Union(IntentionalShutdownCause, DedicatedWorkerDisconnectBroadcast) {}
6
+ export class All extends Schema.Union(IntentionalShutdownCause, UnexpectedError) {}
9
7
 
10
8
  /**
11
9
  * Used internally by an adapter to shutdown gracefully.