@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,44 +1,40 @@
1
1
  import type {
2
2
  Deferred,
3
3
  Effect,
4
- Fiber,
5
4
  HttpClient,
6
5
  Option,
7
6
  Queue,
8
7
  Scope,
8
+ Stream,
9
+ Subscribable,
9
10
  SubscriptionRef,
10
- WebChannel,
11
11
  } from '@livestore/utils/effect'
12
12
  import { Context, Schema } from '@livestore/utils/effect'
13
+ import type { MeshNode } from '@livestore/webmesh'
13
14
 
15
+ import type { LeaderPullCursor, SqliteError } from '../adapter-types.js'
14
16
  import type {
15
17
  BootStatus,
16
18
  Devtools,
17
- InvalidPushError,
18
- MakeSynchronousDatabase,
19
+ LeaderAheadError,
20
+ MakeSqliteDb,
21
+ MigrationsReport,
19
22
  PersistenceInfo,
23
+ SqliteDb,
20
24
  SyncBackend,
21
- SynchronousDatabase,
22
25
  UnexpectedError,
23
26
  } from '../index.js'
24
- import type { EventId, LiveStoreSchema, MutationEvent } from '../schema/mod.js'
27
+ import type { EventSequenceNumber, LiveStoreEvent, LiveStoreSchema } from '../schema/mod.js'
25
28
  import type * as SyncState from '../sync/syncstate.js'
26
29
  import type { ShutdownChannel } from './shutdown-channel.js'
27
30
 
28
31
  export type ShutdownState = 'running' | 'shutting-down'
29
32
 
30
- export class OuterWorkerCtx extends Context.Tag('OuterWorkerCtx')<
31
- OuterWorkerCtx,
32
- {
33
- innerFiber: Fiber.RuntimeFiber<any, any>
34
- }
35
- >() {}
36
-
37
33
  export const InitialSyncOptionsSkip = Schema.TaggedStruct('Skip', {})
38
34
  export type InitialSyncOptionsSkip = typeof InitialSyncOptionsSkip.Type
39
35
 
40
36
  export const InitialSyncOptionsBlocking = Schema.TaggedStruct('Blocking', {
41
- timeout: Schema.DurationFromMillis,
37
+ timeout: Schema.Union(Schema.DurationFromMillis, Schema.Number),
42
38
  })
43
39
 
44
40
  export type InitialSyncOptionsBlocking = typeof InitialSyncOptionsBlocking.Type
@@ -47,7 +43,7 @@ export const InitialSyncOptions = Schema.Union(InitialSyncOptionsSkip, InitialSy
47
43
  export type InitialSyncOptions = typeof InitialSyncOptions.Type
48
44
 
49
45
  export type InitialSyncInfo = Option.Option<{
50
- cursor: EventId.EventId
46
+ cursor: EventSequenceNumber.EventSequenceNumber
51
47
  metadata: Option.Option<Schema.JsonValue>
52
48
  }>
53
49
 
@@ -55,8 +51,8 @@ export type InitialSyncInfo = Option.Option<{
55
51
  // | { _tag: 'Recreate'; snapshotRef: Ref.Ref<Uint8Array | undefined>; syncInfo: InitialSyncInfo }
56
52
  // | { _tag: 'Reuse'; syncInfo: InitialSyncInfo }
57
53
 
58
- export type LeaderDatabase = SynchronousDatabase<{ dbPointer: number; persistenceInfo: PersistenceInfo }>
59
- export type PersistenceInfoPair = { db: PersistenceInfo; mutationLog: PersistenceInfo }
54
+ export type LeaderSqliteDb = SqliteDb<{ dbPointer: number; persistenceInfo: PersistenceInfo }>
55
+ export type PersistenceInfoPair = { state: PersistenceInfo; eventlog: PersistenceInfo }
60
56
 
61
57
  export type DevtoolsOptions =
62
58
  | {
@@ -64,65 +60,115 @@ export type DevtoolsOptions =
64
60
  }
65
61
  | {
66
62
  enabled: true
67
- makeContext: Effect.Effect<
63
+ boot: Effect.Effect<
68
64
  {
69
- devtoolsWebChannel: WebChannel.WebChannel<Devtools.MessageToAppLeader, Devtools.MessageFromAppLeader>
65
+ node: MeshNode
70
66
  persistenceInfo: PersistenceInfoPair
67
+ mode: 'proxy' | 'direct'
71
68
  },
72
69
  UnexpectedError,
73
- Scope.Scope
70
+ Scope.Scope | HttpClient.HttpClient | LeaderThreadCtx
74
71
  >
75
72
  }
76
73
 
74
+ export type DevtoolsContext =
75
+ | {
76
+ enabled: true
77
+ // syncBackendPullLatch: Effect.Latch
78
+ // syncBackendPushLatch: Effect.Latch
79
+ syncBackendLatch: Effect.Latch
80
+ syncBackendLatchState: SubscriptionRef.SubscriptionRef<{ latchClosed: boolean }>
81
+ }
82
+ | {
83
+ enabled: false
84
+ }
85
+
77
86
  export class LeaderThreadCtx extends Context.Tag('LeaderThreadCtx')<
78
87
  LeaderThreadCtx,
79
88
  {
80
89
  schema: LiveStoreSchema
81
90
  storeId: string
82
91
  clientId: string
83
- makeSyncDb: MakeSynchronousDatabase
84
- db: LeaderDatabase
85
- dbLog: LeaderDatabase
92
+ makeSqliteDb: MakeSqliteDb
93
+ dbState: LeaderSqliteDb
94
+ dbEventlog: LeaderSqliteDb
86
95
  bootStatusQueue: Queue.Queue<BootStatus>
87
96
  // TODO we should find a more elegant way to handle cases which need this ref for their implementation
88
97
  shutdownStateSubRef: SubscriptionRef.SubscriptionRef<ShutdownState>
89
98
  shutdownChannel: ShutdownChannel
90
- mutationEventSchema: MutationEvent.ForMutationDefRecord<any>
91
- // devtools: DevtoolsContext
99
+ eventSchema: LiveStoreEvent.ForEventDefRecord<any>
100
+ devtools: DevtoolsContext
92
101
  syncBackend: SyncBackend | undefined
93
- syncProcessor: SyncProcessor
94
- connectedClientSessionPullQueues: PullQueueSet
95
- /** e.g. used for `store.__dev` APIs */
96
- extraIncomingMessagesQueue: Queue.Queue<Devtools.MessageToAppLeader>
102
+ syncProcessor: LeaderSyncProcessor
103
+ materializeEvent: MaterializeEvent
104
+ initialState: {
105
+ leaderHead: EventSequenceNumber.EventSequenceNumber
106
+ migrationsReport: MigrationsReport
107
+ }
108
+ /**
109
+ * e.g. used for `store._dev` APIs
110
+ *
111
+ * This is currently separated from `.devtools` as it also needs to work when devtools are disabled
112
+ */
113
+ extraIncomingMessagesQueue: Queue.Queue<Devtools.Leader.MessageToApp>
97
114
  }
98
115
  >() {}
99
116
 
117
+ export type MaterializeEvent = (
118
+ eventEncoded: LiveStoreEvent.EncodedWithMeta,
119
+ options?: {
120
+ /** Needed for rematerializeFromEventlog */
121
+ skipEventlog?: boolean
122
+ },
123
+ ) => Effect.Effect<
124
+ { sessionChangeset: { _tag: 'sessionChangeset'; data: Uint8Array; debug: any } | { _tag: 'no-op' } },
125
+ SqliteError | UnexpectedError
126
+ >
127
+
100
128
  export type InitialBlockingSyncContext = {
101
129
  blockingDeferred: Deferred.Deferred<void> | undefined
102
130
  update: (_: { remaining: number; processed: number }) => Effect.Effect<void>
103
131
  }
104
132
 
105
- export type PullQueueItem = {
106
- payload: SyncState.PayloadUpstream
107
- remaining: number
108
- }
109
-
110
- export interface SyncProcessor {
133
+ export interface LeaderSyncProcessor {
134
+ /** Used by client sessions to subscribe to upstream sync state changes */
135
+ pull: (args: {
136
+ cursor: LeaderPullCursor
137
+ }) => Stream.Stream<{ payload: typeof SyncState.PayloadUpstream.Type; mergeCounter: number }, UnexpectedError>
138
+ /** The `pullQueue` API can be used instead of `pull` when more convenient */
139
+ pullQueue: (args: {
140
+ cursor: LeaderPullCursor
141
+ }) => Effect.Effect<
142
+ Queue.Queue<{ payload: typeof SyncState.PayloadUpstream.Type; mergeCounter: number }>,
143
+ UnexpectedError,
144
+ Scope.Scope
145
+ >
146
+
147
+ /** Used by client sessions to push events to the leader thread */
111
148
  push: (
112
149
  /** `batch` needs to follow the same rules as `batch` in `SyncBackend.push` */
113
- batch: ReadonlyArray<MutationEvent.EncodedWithMeta>,
114
- ) => Effect.Effect<void, UnexpectedError | InvalidPushError, HttpClient.HttpClient | LeaderThreadCtx>
115
-
116
- pushPartial: (mutationEvent: MutationEvent.PartialAnyEncoded) => Effect.Effect<void, UnexpectedError, LeaderThreadCtx>
117
- boot: (args: {
118
- dbReady: Deferred.Deferred<void>
119
- }) => Effect.Effect<void, UnexpectedError, LeaderThreadCtx | Scope.Scope | HttpClient.HttpClient>
120
- syncState: Effect.Effect<SyncState.SyncState, UnexpectedError>
121
- }
122
-
123
- export interface PullQueueSet {
124
- makeQueue: (
125
- since: EventId.EventId,
126
- ) => Effect.Effect<Queue.Queue<PullQueueItem>, UnexpectedError, Scope.Scope | LeaderThreadCtx>
127
- offer: (item: PullQueueItem) => Effect.Effect<void, UnexpectedError, LeaderThreadCtx>
150
+ batch: ReadonlyArray<LiveStoreEvent.EncodedWithMeta>,
151
+ options?: {
152
+ /**
153
+ * If true, the effect will only finish when the local push has been processed (i.e. succeeded or was rejected).
154
+ * @default false
155
+ */
156
+ waitForProcessing?: boolean
157
+ },
158
+ ) => Effect.Effect<void, LeaderAheadError>
159
+
160
+ /** Currently only used by devtools which don't provide their own event numbers */
161
+ pushPartial: (args: {
162
+ event: LiveStoreEvent.PartialAnyEncoded
163
+ clientId: string
164
+ sessionId: string
165
+ }) => Effect.Effect<void, UnexpectedError>
166
+
167
+ boot: Effect.Effect<
168
+ { initialLeaderHead: EventSequenceNumber.EventSequenceNumber },
169
+ UnexpectedError,
170
+ LeaderThreadCtx | Scope.Scope | HttpClient.HttpClient
171
+ >
172
+ syncState: Subscribable.Subscribable<SyncState.SyncState>
173
+ getMergeCounter: () => number
128
174
  }
@@ -0,0 +1,136 @@
1
+ import type { Scope, SubscriptionRef } from '@livestore/utils/effect'
2
+ import { Effect, Stream } from '@livestore/utils/effect'
3
+ import * as Webmesh from '@livestore/webmesh'
4
+
5
+ import type {
6
+ AdapterArgs,
7
+ ClientSession,
8
+ ClientSessionLeaderThreadProxy,
9
+ LockStatus,
10
+ SqliteDb,
11
+ UnexpectedError,
12
+ } from './adapter-types.js'
13
+ import * as Devtools from './devtools/mod.js'
14
+ import { liveStoreVersion } from './version.js'
15
+
16
+ declare global {
17
+ // eslint-disable-next-line no-var
18
+ var __debugWebmeshNode: any
19
+ }
20
+
21
+ export const makeClientSession = <R>({
22
+ storeId,
23
+ clientId,
24
+ sessionId,
25
+ isLeader,
26
+ devtoolsEnabled,
27
+ connectDevtoolsToStore,
28
+ lockStatus,
29
+ leaderThread,
30
+ schema,
31
+ sqliteDb,
32
+ shutdown,
33
+ connectWebmeshNode,
34
+ webmeshMode,
35
+ registerBeforeUnload,
36
+ debugInstanceId,
37
+ }: AdapterArgs & {
38
+ clientId: string
39
+ sessionId: string
40
+ isLeader: boolean
41
+ lockStatus: SubscriptionRef.SubscriptionRef<LockStatus>
42
+ leaderThread: ClientSessionLeaderThreadProxy
43
+ sqliteDb: SqliteDb
44
+ connectWebmeshNode: (args: {
45
+ webmeshNode: Webmesh.MeshNode
46
+ sessionInfo: Devtools.SessionInfo.SessionInfo
47
+ }) => Effect.Effect<void, UnexpectedError, Scope.Scope | R>
48
+ webmeshMode: 'direct' | 'proxy'
49
+ registerBeforeUnload: (onBeforeUnload: () => void) => () => void
50
+ }): Effect.Effect<ClientSession, never, Scope.Scope | R> =>
51
+ Effect.gen(function* () {
52
+ const devtools: ClientSession['devtools'] = devtoolsEnabled
53
+ ? { enabled: true, pullLatch: yield* Effect.makeLatch(true), pushLatch: yield* Effect.makeLatch(true) }
54
+ : { enabled: false }
55
+
56
+ if (devtoolsEnabled) {
57
+ yield* Effect.gen(function* () {
58
+ const webmeshNode = yield* Webmesh.makeMeshNode(
59
+ Devtools.makeNodeName.client.session({ storeId, clientId, sessionId }),
60
+ )
61
+
62
+ globalThis.__debugWebmeshNode = webmeshNode
63
+
64
+ const schemaAlias = schema.devtools.alias
65
+ const sessionInfo = Devtools.SessionInfo.SessionInfo.make({
66
+ storeId,
67
+ clientId,
68
+ sessionId,
69
+ schemaAlias,
70
+ isLeader,
71
+ })
72
+
73
+ yield* connectWebmeshNode({ webmeshNode, sessionInfo })
74
+
75
+ const sessionInfoBroadcastChannel = yield* Devtools.makeSessionInfoBroadcastChannel(webmeshNode)
76
+
77
+ yield* Devtools.SessionInfo.provideSessionInfo({
78
+ webChannel: sessionInfoBroadcastChannel,
79
+ sessionInfo,
80
+ }).pipe(Effect.tapCauseLogPretty, Effect.forkScoped)
81
+
82
+ yield* webmeshNode.listenForChannel.pipe(
83
+ Stream.filter(
84
+ (res) =>
85
+ Devtools.isChannelName.devtoolsClientSession(res.channelName, { storeId, clientId, sessionId }) &&
86
+ res.mode === webmeshMode,
87
+ ),
88
+ Stream.tap(
89
+ Effect.fnUntraced(
90
+ function* ({ channelName, source }) {
91
+ const clientSessionDevtoolsChannel = yield* webmeshNode.makeChannel({
92
+ target: source,
93
+ channelName,
94
+ schema: { listen: Devtools.ClientSession.MessageToApp, send: Devtools.ClientSession.MessageFromApp },
95
+ mode: webmeshMode,
96
+ })
97
+
98
+ const sendDisconnect = clientSessionDevtoolsChannel
99
+ .send(Devtools.ClientSession.Disconnect.make({ clientId, liveStoreVersion, sessionId }))
100
+ .pipe(Effect.orDie)
101
+
102
+ // Disconnect on shutdown (e.g. when switching stores)
103
+ yield* Effect.addFinalizer(() => sendDisconnect)
104
+
105
+ // Disconnect on before unload
106
+ yield* Effect.acquireRelease(
107
+ Effect.sync(() => registerBeforeUnload(() => sendDisconnect.pipe(Effect.runFork))),
108
+ (unsub) => Effect.sync(() => unsub()),
109
+ )
110
+
111
+ yield* connectDevtoolsToStore(clientSessionDevtoolsChannel)
112
+ },
113
+ Effect.tapCauseLogPretty,
114
+ Effect.forkScoped,
115
+ ),
116
+ ),
117
+ Stream.runDrain,
118
+ )
119
+ }).pipe(
120
+ Effect.withSpan('@livestore/common:make-client-session:devtools'),
121
+ Effect.tapCauseLogPretty,
122
+ Effect.forkScoped,
123
+ )
124
+ }
125
+
126
+ return {
127
+ sqliteDb,
128
+ leaderThread,
129
+ devtools,
130
+ lockStatus,
131
+ clientId,
132
+ sessionId,
133
+ shutdown,
134
+ debugInstanceId,
135
+ } satisfies ClientSession
136
+ })
@@ -0,0 +1,138 @@
1
+ import { isNil, isReadonlyArray } from '@livestore/utils'
2
+ import { Schema } from '@livestore/utils/effect'
3
+
4
+ import type { SqliteDb } from './adapter-types.js'
5
+ import { SessionIdSymbol } from './adapter-types.js'
6
+ import type { EventDef, Materializer, MaterializerContextQuery, MaterializerResult } from './schema/EventDef.js'
7
+ import type * as LiveStoreEvent from './schema/LiveStoreEvent.js'
8
+ import type { QueryBuilder } from './schema/state/sqlite/query-builder/api.js'
9
+ import { isQueryBuilder } from './schema/state/sqlite/query-builder/api.js'
10
+ import { getResultSchema } from './schema/state/sqlite/query-builder/impl.js'
11
+ import { type BindValues } from './sql-queries/sql-queries.js'
12
+ import type { ParamsObject, PreparedBindValues } from './util.js'
13
+ import { prepareBindValues } from './util.js'
14
+
15
+ export const getExecArgsFromEvent = ({
16
+ eventDef,
17
+ materializer,
18
+ db,
19
+ event,
20
+ }: {
21
+ eventDef: EventDef.AnyWithoutFn
22
+ materializer: Materializer
23
+ db: SqliteDb
24
+ /** Both encoded and decoded events are supported to reduce the number of times we need to decode/encode */
25
+ event:
26
+ | {
27
+ decoded: LiveStoreEvent.AnyDecoded | LiveStoreEvent.PartialAnyDecoded
28
+ encoded: undefined
29
+ }
30
+ | {
31
+ decoded: undefined
32
+ encoded: LiveStoreEvent.AnyEncoded | LiveStoreEvent.PartialAnyEncoded
33
+ }
34
+ }): ReadonlyArray<{
35
+ statementSql: string
36
+ bindValues: PreparedBindValues
37
+ writeTables: ReadonlySet<string> | undefined
38
+ }> => {
39
+ const eventArgsDecoded =
40
+ event.decoded === undefined ? Schema.decodeUnknownSync(eventDef.schema)(event.encoded!.args) : event.decoded.args
41
+
42
+ const eventArgsEncoded = isNil(event.decoded?.args)
43
+ ? undefined
44
+ : Schema.encodeUnknownSync(eventDef.schema)(event.decoded!.args)
45
+
46
+ const query: MaterializerContextQuery = (
47
+ rawQueryOrQueryBuilder:
48
+ | {
49
+ query: string
50
+ bindValues: ParamsObject
51
+ }
52
+ | QueryBuilder.Any,
53
+ ) => {
54
+ if (isQueryBuilder(rawQueryOrQueryBuilder)) {
55
+ const { query, bindValues } = rawQueryOrQueryBuilder.asSql()
56
+ const rawResults = db.select(query, prepareBindValues(bindValues, query))
57
+ const resultSchema = getResultSchema(rawQueryOrQueryBuilder)
58
+ return Schema.decodeSync(resultSchema)(rawResults)
59
+ } else {
60
+ const { query, bindValues } = rawQueryOrQueryBuilder
61
+ return db.select(query, prepareBindValues(bindValues, query))
62
+ }
63
+ }
64
+
65
+ const res = materializer(eventArgsDecoded, {
66
+ eventDef,
67
+ query,
68
+ // TODO properly implement this
69
+ currentFacts: new Map(),
70
+ })
71
+
72
+ const statementRes = mapMaterializerResult(res)
73
+
74
+ return statementRes.map((statementRes) => {
75
+ const statementSql = statementRes.sql
76
+
77
+ const bindValues = typeof statementRes === 'string' ? eventArgsEncoded : statementRes.bindValues
78
+
79
+ const writeTables = typeof statementRes === 'string' ? undefined : statementRes.writeTables
80
+
81
+ return { statementSql, bindValues: prepareBindValues(bindValues ?? {}, statementSql), writeTables }
82
+ })
83
+ }
84
+
85
+ const mapMaterializerResult = (
86
+ materializerResult: MaterializerResult | ReadonlyArray<MaterializerResult>,
87
+ ): ReadonlyArray<{
88
+ sql: string
89
+ bindValues: BindValues
90
+ writeTables: ReadonlySet<string> | undefined
91
+ }> => {
92
+ if (isReadonlyArray(materializerResult)) {
93
+ return materializerResult.flatMap(mapMaterializerResult)
94
+ }
95
+ if (isQueryBuilder(materializerResult)) {
96
+ const { query, bindValues } = materializerResult.asSql()
97
+ return [{ sql: query, bindValues: bindValues as BindValues, writeTables: undefined }]
98
+ } else if (typeof materializerResult === 'string') {
99
+ return [{ sql: materializerResult, bindValues: {} as BindValues, writeTables: undefined }]
100
+ } else {
101
+ return [
102
+ {
103
+ sql: materializerResult.sql,
104
+ bindValues: materializerResult.bindValues,
105
+ writeTables: materializerResult.writeTables,
106
+ },
107
+ ]
108
+ }
109
+ }
110
+
111
+ // NOTE we should explore whether there is a more elegant solution
112
+ // e.g. by leveraging the schema to replace the sessionIdSymbol
113
+ export const replaceSessionIdSymbol = (
114
+ bindValues: Record<string, unknown> | ReadonlyArray<unknown>,
115
+ sessionId: string,
116
+ ) => {
117
+ deepReplaceValue(bindValues, SessionIdSymbol, sessionId)
118
+ }
119
+
120
+ const deepReplaceValue = <S, R>(input: any, searchValue: S, replaceValue: R): void => {
121
+ if (Array.isArray(input)) {
122
+ for (const i in input) {
123
+ if (input[i] === searchValue) {
124
+ input[i] = replaceValue
125
+ } else {
126
+ deepReplaceValue(input[i], searchValue, replaceValue)
127
+ }
128
+ }
129
+ } else if (typeof input === 'object' && input !== null) {
130
+ for (const key in input) {
131
+ if (input[key] === searchValue) {
132
+ input[key] = replaceValue
133
+ } else {
134
+ deepReplaceValue(input[key], searchValue, replaceValue)
135
+ }
136
+ }
137
+ }
138
+ }
package/src/otel.ts CHANGED
@@ -18,3 +18,11 @@ export const provideOtel =
18
18
  Effect.provide(TracingLive),
19
19
  )
20
20
  }
21
+
22
+ export const getDurationMsFromSpan = (span: otel.Span): number => {
23
+ const durationHr: [seconds: number, nanos: number] = (span as any)._duration
24
+ return durationHr[0] * 1000 + durationHr[1] / 1_000_000
25
+ }
26
+
27
+ export const getStartTimeHighResFromSpan = (span: otel.Span): DOMHighResTimeStamp =>
28
+ (span as any)._performanceStartTime as DOMHighResTimeStamp
@@ -0,0 +1,117 @@
1
+ import { memoizeByRef } from '@livestore/utils'
2
+ import { Chunk, Effect, Option, Schema, Stream } from '@livestore/utils/effect'
3
+
4
+ import { type SqliteDb, UnexpectedError } from './adapter-types.js'
5
+ import type { MaterializeEvent } from './leader-thread/mod.js'
6
+ import type { EventDef, LiveStoreSchema } from './schema/mod.js'
7
+ import { EventSequenceNumber, getEventDef, LiveStoreEvent, SystemTables } from './schema/mod.js'
8
+ import type { PreparedBindValues } from './util.js'
9
+ import { sql } from './util.js'
10
+
11
+ export const rematerializeFromEventlog = ({
12
+ dbEventlog,
13
+ // TODO re-use this db when bringing back the boot in-memory db implementation
14
+ // db,
15
+ schema,
16
+ onProgress,
17
+ materializeEvent,
18
+ }: {
19
+ dbEventlog: SqliteDb
20
+ // db: SqliteDb
21
+ schema: LiveStoreSchema
22
+ onProgress: (_: { done: number; total: number }) => Effect.Effect<void>
23
+ materializeEvent: MaterializeEvent
24
+ }) =>
25
+ Effect.gen(function* () {
26
+ const eventsCount = dbEventlog.select<{ count: number }>(
27
+ `SELECT COUNT(*) AS count FROM ${SystemTables.EVENTLOG_META_TABLE}`,
28
+ )[0]!.count
29
+
30
+ const hashEvent = memoizeByRef((event: EventDef.AnyWithoutFn) => Schema.hash(event.schema))
31
+
32
+ const processEvent = (row: SystemTables.EventlogMetaRow) =>
33
+ Effect.gen(function* () {
34
+ const eventDef = getEventDef(schema, row.name)
35
+
36
+ if (hashEvent(eventDef.eventDef) !== row.schemaHash) {
37
+ yield* Effect.logWarning(
38
+ `Schema hash mismatch for event definition ${row.name}. Trying to materialize event anyway.`,
39
+ )
40
+ }
41
+
42
+ const args = JSON.parse(row.argsJson)
43
+
44
+ // Checking whether the schema has changed in an incompatible way
45
+ yield* Schema.decodeUnknown(eventDef.eventDef.schema)(args).pipe(
46
+ Effect.mapError((cause) =>
47
+ UnexpectedError.make({
48
+ cause,
49
+ note: `\
50
+ There was an error during rematerializing from the eventlog while decoding
51
+ the persisted event args for event definition "${row.name}".
52
+ This likely means the schema has changed in an incompatible way.
53
+ `,
54
+ }),
55
+ ),
56
+ )
57
+
58
+ const eventEncoded = LiveStoreEvent.EncodedWithMeta.make({
59
+ seqNum: { global: row.seqNumGlobal, client: row.seqNumClient },
60
+ parentSeqNum: { global: row.parentSeqNumGlobal, client: row.parentSeqNumClient },
61
+ name: row.name,
62
+ args,
63
+ clientId: row.clientId,
64
+ sessionId: row.sessionId,
65
+ })
66
+
67
+ yield* materializeEvent(eventEncoded, { skipEventlog: true })
68
+ }).pipe(Effect.withSpan(`@livestore/common:rematerializeFromEventlog:processEvent`))
69
+
70
+ const CHUNK_SIZE = 100
71
+
72
+ const stmt = dbEventlog.prepare(sql`\
73
+ SELECT * FROM ${SystemTables.EVENTLOG_META_TABLE}
74
+ WHERE seqNumGlobal > $seqNumGlobal OR (seqNumGlobal = $seqNumGlobal AND seqNumClient > $seqNumClient)
75
+ ORDER BY seqNumGlobal ASC, seqNumClient ASC
76
+ LIMIT ${CHUNK_SIZE}
77
+ `)
78
+
79
+ let processedEvents = 0
80
+
81
+ yield* Stream.unfoldChunk<
82
+ Chunk.Chunk<SystemTables.EventlogMetaRow> | { _tag: 'Initial ' },
83
+ SystemTables.EventlogMetaRow
84
+ >({ _tag: 'Initial ' }, (item) => {
85
+ // End stream if no more rows
86
+ if (Chunk.isChunk(item) && item.length === 0) return Option.none()
87
+
88
+ const lastId = Chunk.isChunk(item)
89
+ ? Chunk.last(item).pipe(
90
+ Option.map((_) => ({ global: _.seqNumGlobal, client: _.seqNumClient })),
91
+ Option.getOrElse(() => EventSequenceNumber.ROOT),
92
+ )
93
+ : EventSequenceNumber.ROOT
94
+ const nextItem = Chunk.fromIterable(
95
+ stmt.select<SystemTables.EventlogMetaRow>({
96
+ $seqNumGlobal: lastId?.global,
97
+ $seqNumClient: lastId?.client,
98
+ } as any as PreparedBindValues),
99
+ )
100
+ const prevItem = Chunk.isChunk(item) ? item : Chunk.empty()
101
+ return Option.some([prevItem, nextItem])
102
+ }).pipe(
103
+ Stream.bufferChunks({ capacity: 2 }),
104
+ Stream.tap((row) =>
105
+ Effect.gen(function* () {
106
+ yield* processEvent(row)
107
+
108
+ processedEvents++
109
+ yield* onProgress({ done: processedEvents, total: eventsCount })
110
+ }),
111
+ ),
112
+ Stream.runDrain,
113
+ )
114
+ }).pipe(
115
+ Effect.withPerformanceMeasure('@livestore/common:rematerializeFromEventlog'),
116
+ Effect.withSpan('@livestore/common:rematerializeFromEventlog'),
117
+ )