@livestore/common 0.4.0 → 0.5.0-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (421) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/ClientSessionLeaderThreadProxy.d.ts +1 -1
  3. package/dist/ClientSessionLeaderThreadProxy.d.ts.map +1 -1
  4. package/dist/MaterializationJournal.d.ts +44 -0
  5. package/dist/MaterializationJournal.d.ts.map +1 -0
  6. package/dist/MaterializationJournal.js +112 -0
  7. package/dist/MaterializationJournal.js.map +1 -0
  8. package/dist/StateHead.d.ts +26 -0
  9. package/dist/StateHead.d.ts.map +1 -0
  10. package/dist/StateHead.js +50 -0
  11. package/dist/StateHead.js.map +1 -0
  12. package/dist/WorkerTransportError.d.ts +3 -3
  13. package/dist/WorkerTransportError.d.ts.map +1 -1
  14. package/dist/WorkerTransportError.js +3 -3
  15. package/dist/WorkerTransportError.js.map +1 -1
  16. package/dist/__tests__/fixture.d.ts +1 -1
  17. package/dist/__tests__/fixture.d.ts.map +1 -1
  18. package/dist/__tests__/fixture.js +3 -3
  19. package/dist/__tests__/fixture.js.map +1 -1
  20. package/dist/adapter-types.d.ts +29 -57
  21. package/dist/adapter-types.d.ts.map +1 -1
  22. package/dist/adapter-types.js +20 -37
  23. package/dist/adapter-types.js.map +1 -1
  24. package/dist/debug-info.d.ts +56 -56
  25. package/dist/debug-info.d.ts.map +1 -1
  26. package/dist/debug-info.js +28 -41
  27. package/dist/debug-info.js.map +1 -1
  28. package/dist/defs.d.ts +9 -9
  29. package/dist/defs.js +2 -2
  30. package/dist/devtools/devtools-compatibility.test.js +1 -0
  31. package/dist/devtools/devtools-compatibility.test.js.map +1 -1
  32. package/dist/devtools/devtools-messages-client-session.d.ts +520 -332
  33. package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -1
  34. package/dist/devtools/devtools-messages-client-session.js +76 -74
  35. package/dist/devtools/devtools-messages-client-session.js.map +1 -1
  36. package/dist/devtools/devtools-messages-common.d.ts +27 -27
  37. package/dist/devtools/devtools-messages-common.d.ts.map +1 -1
  38. package/dist/devtools/devtools-messages-common.js +5 -5
  39. package/dist/devtools/devtools-messages-common.js.map +1 -1
  40. package/dist/devtools/devtools-messages-leader.d.ts +405 -343
  41. package/dist/devtools/devtools-messages-leader.d.ts.map +1 -1
  42. package/dist/devtools/devtools-messages-leader.js +101 -89
  43. package/dist/devtools/devtools-messages-leader.js.map +1 -1
  44. package/dist/devtools/devtools-sessioninfo.d.ts +18 -19
  45. package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -1
  46. package/dist/devtools/devtools-sessioninfo.js +8 -5
  47. package/dist/devtools/devtools-sessioninfo.js.map +1 -1
  48. package/dist/devtools/mod.d.ts +4 -5
  49. package/dist/devtools/mod.d.ts.map +1 -1
  50. package/dist/devtools/mod.js +9 -5
  51. package/dist/devtools/mod.js.map +1 -1
  52. package/dist/errors.d.ts +45 -69
  53. package/dist/errors.d.ts.map +1 -1
  54. package/dist/errors.js +18 -16
  55. package/dist/errors.js.map +1 -1
  56. package/dist/index.d.ts +4 -1
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +4 -1
  59. package/dist/index.js.map +1 -1
  60. package/dist/leader-thread/LeaderSyncProcessor.d.ts +66 -18
  61. package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
  62. package/dist/leader-thread/LeaderSyncProcessor.js +519 -461
  63. package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
  64. package/dist/leader-thread/RejectedPushError.d.ts +67 -36
  65. package/dist/leader-thread/RejectedPushError.d.ts.map +1 -1
  66. package/dist/leader-thread/RejectedPushError.js +24 -5
  67. package/dist/leader-thread/RejectedPushError.js.map +1 -1
  68. package/dist/leader-thread/connection.d.ts +1 -0
  69. package/dist/leader-thread/connection.d.ts.map +1 -1
  70. package/dist/leader-thread/connection.js +9 -8
  71. package/dist/leader-thread/connection.js.map +1 -1
  72. package/dist/leader-thread/eventlog.d.ts +4 -4
  73. package/dist/leader-thread/eventlog.d.ts.map +1 -1
  74. package/dist/leader-thread/eventlog.js +6 -6
  75. package/dist/leader-thread/eventlog.js.map +1 -1
  76. package/dist/leader-thread/leader-worker-devtools.d.ts +1 -1
  77. package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
  78. package/dist/leader-thread/leader-worker-devtools.js +33 -17
  79. package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
  80. package/dist/leader-thread/make-leader-thread-layer.d.ts +9 -5
  81. package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
  82. package/dist/leader-thread/make-leader-thread-layer.js +25 -35
  83. package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
  84. package/dist/leader-thread/make-leader-thread-layer.test.js +7 -7
  85. package/dist/leader-thread/make-leader-thread-layer.test.js.map +1 -1
  86. package/dist/leader-thread/materialize-event.d.ts +2 -1
  87. package/dist/leader-thread/materialize-event.d.ts.map +1 -1
  88. package/dist/leader-thread/materialize-event.js +4 -0
  89. package/dist/leader-thread/materialize-event.js.map +1 -1
  90. package/dist/leader-thread/recreate-db.d.ts.map +1 -1
  91. package/dist/leader-thread/recreate-db.js +18 -39
  92. package/dist/leader-thread/recreate-db.js.map +1 -1
  93. package/dist/leader-thread/shutdown-channel.d.ts +2 -6
  94. package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
  95. package/dist/leader-thread/shutdown-channel.js +2 -3
  96. package/dist/leader-thread/shutdown-channel.js.map +1 -1
  97. package/dist/leader-thread/stream-events.d.ts +4 -7
  98. package/dist/leader-thread/stream-events.d.ts.map +1 -1
  99. package/dist/leader-thread/stream-events.js +13 -16
  100. package/dist/leader-thread/stream-events.js.map +1 -1
  101. package/dist/leader-thread/types.d.ts +32 -69
  102. package/dist/leader-thread/types.d.ts.map +1 -1
  103. package/dist/leader-thread/types.js +5 -5
  104. package/dist/leader-thread/types.js.map +1 -1
  105. package/dist/logging.d.ts +5 -30
  106. package/dist/logging.d.ts.map +1 -1
  107. package/dist/logging.js +1 -32
  108. package/dist/logging.js.map +1 -1
  109. package/dist/make-client-session.d.ts +1 -2
  110. package/dist/make-client-session.d.ts.map +1 -1
  111. package/dist/make-client-session.js +3 -3
  112. package/dist/make-client-session.js.map +1 -1
  113. package/dist/materializer-helper.d.ts +0 -1
  114. package/dist/materializer-helper.d.ts.map +1 -1
  115. package/dist/materializer-helper.js +7 -35
  116. package/dist/materializer-helper.js.map +1 -1
  117. package/dist/otel.d.ts +2 -3
  118. package/dist/otel.d.ts.map +1 -1
  119. package/dist/otel.js +2 -7
  120. package/dist/otel.js.map +1 -1
  121. package/dist/rematerialize-from-eventlog.d.ts.map +1 -1
  122. package/dist/rematerialize-from-eventlog.js +28 -26
  123. package/dist/rematerialize-from-eventlog.js.map +1 -1
  124. package/dist/schema/EventDef/define.d.ts +4 -4
  125. package/dist/schema/EventDef/define.d.ts.map +1 -1
  126. package/dist/schema/EventDef/define.js +5 -5
  127. package/dist/schema/EventDef/define.js.map +1 -1
  128. package/dist/schema/EventDef/define.test.d.ts +2 -0
  129. package/dist/schema/EventDef/define.test.d.ts.map +1 -0
  130. package/dist/schema/EventDef/define.test.js +23 -0
  131. package/dist/schema/EventDef/define.test.js.map +1 -0
  132. package/dist/schema/EventDef/deprecated.d.ts +8 -13
  133. package/dist/schema/EventDef/deprecated.d.ts.map +1 -1
  134. package/dist/schema/EventDef/deprecated.js +12 -13
  135. package/dist/schema/EventDef/deprecated.js.map +1 -1
  136. package/dist/schema/EventDef/deprecated.test.js +1 -1
  137. package/dist/schema/EventDef/deprecated.test.js.map +1 -1
  138. package/dist/schema/EventDef/event-def.d.ts +1 -1
  139. package/dist/schema/EventDef/event-def.d.ts.map +1 -1
  140. package/dist/schema/EventSequenceNumber/client.d.ts +12 -12
  141. package/dist/schema/EventSequenceNumber/client.d.ts.map +1 -1
  142. package/dist/schema/EventSequenceNumber/client.js +8 -9
  143. package/dist/schema/EventSequenceNumber/client.js.map +1 -1
  144. package/dist/schema/EventSequenceNumber/global.d.ts +2 -2
  145. package/dist/schema/EventSequenceNumber/global.d.ts.map +1 -1
  146. package/dist/schema/EventSequenceNumber/global.js +1 -1
  147. package/dist/schema/EventSequenceNumber/global.js.map +1 -1
  148. package/dist/schema/EventSequenceNumber.test.js +5 -5
  149. package/dist/schema/EventSequenceNumber.test.js.map +1 -1
  150. package/dist/schema/LiveStoreEvent/client.d.ts +50 -179
  151. package/dist/schema/LiveStoreEvent/client.d.ts.map +1 -1
  152. package/dist/schema/LiveStoreEvent/client.js +32 -29
  153. package/dist/schema/LiveStoreEvent/client.js.map +1 -1
  154. package/dist/schema/LiveStoreEvent/client.test.js +11 -2
  155. package/dist/schema/LiveStoreEvent/client.test.js.map +1 -1
  156. package/dist/schema/LiveStoreEvent/for-event-def.d.ts +7 -7
  157. package/dist/schema/LiveStoreEvent/for-event-def.d.ts.map +1 -1
  158. package/dist/schema/LiveStoreEvent/global.d.ts +6 -6
  159. package/dist/schema/LiveStoreEvent/global.d.ts.map +1 -1
  160. package/dist/schema/LiveStoreEvent/global.js +1 -1
  161. package/dist/schema/LiveStoreEvent/global.js.map +1 -1
  162. package/dist/schema/LiveStoreEvent/input.d.ts +5 -5
  163. package/dist/schema/LiveStoreEvent/input.d.ts.map +1 -1
  164. package/dist/schema/LiveStoreEvent/input.js +3 -3
  165. package/dist/schema/LiveStoreEvent/input.js.map +1 -1
  166. package/dist/schema/mod.d.ts +1 -0
  167. package/dist/schema/mod.d.ts.map +1 -1
  168. package/dist/schema/mod.js +1 -0
  169. package/dist/schema/mod.js.map +1 -1
  170. package/dist/schema/schema.d.ts.map +1 -1
  171. package/dist/schema/schema.js +3 -2
  172. package/dist/schema/schema.js.map +1 -1
  173. package/dist/schema/state/sqlite/client-document-def.d.ts +12 -17
  174. package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -1
  175. package/dist/schema/state/sqlite/client-document-def.js +23 -20
  176. package/dist/schema/state/sqlite/client-document-def.js.map +1 -1
  177. package/dist/schema/state/sqlite/client-document-def.test.js +29 -8
  178. package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -1
  179. package/dist/schema/state/sqlite/column-annotations.d.ts +13 -13
  180. package/dist/schema/state/sqlite/column-annotations.d.ts.map +1 -1
  181. package/dist/schema/state/sqlite/column-annotations.js +13 -15
  182. package/dist/schema/state/sqlite/column-annotations.js.map +1 -1
  183. package/dist/schema/state/sqlite/column-annotations.test.js +19 -43
  184. package/dist/schema/state/sqlite/column-annotations.test.js.map +1 -1
  185. package/dist/schema/state/sqlite/column-def.d.ts +1 -1
  186. package/dist/schema/state/sqlite/column-def.d.ts.map +1 -1
  187. package/dist/schema/state/sqlite/column-def.js +57 -31
  188. package/dist/schema/state/sqlite/column-def.js.map +1 -1
  189. package/dist/schema/state/sqlite/column-def.test.js +118 -72
  190. package/dist/schema/state/sqlite/column-def.test.js.map +1 -1
  191. package/dist/schema/state/sqlite/column-spec.js.map +1 -1
  192. package/dist/schema/state/sqlite/column-spec.test.js +2 -2
  193. package/dist/schema/state/sqlite/db-schema/ast/sqlite.d.ts +2 -2
  194. package/dist/schema/state/sqlite/db-schema/ast/sqlite.d.ts.map +1 -1
  195. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js +13 -4
  196. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js.map +1 -1
  197. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts +9 -9
  198. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts.map +1 -1
  199. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js +8 -13
  200. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js.map +1 -1
  201. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js +27 -16
  202. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js.map +1 -1
  203. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts +13 -11
  204. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts.map +1 -1
  205. package/dist/schema/state/sqlite/db-schema/dsl/mod.js +5 -3
  206. package/dist/schema/state/sqlite/db-schema/dsl/mod.js.map +1 -1
  207. package/dist/schema/state/sqlite/mod.d.ts +1 -3
  208. package/dist/schema/state/sqlite/mod.d.ts.map +1 -1
  209. package/dist/schema/state/sqlite/mod.js +1 -1
  210. package/dist/schema/state/sqlite/mod.js.map +1 -1
  211. package/dist/schema/state/sqlite/persistence.d.ts +11 -0
  212. package/dist/schema/state/sqlite/persistence.d.ts.map +1 -0
  213. package/dist/schema/state/sqlite/persistence.js +10 -0
  214. package/dist/schema/state/sqlite/persistence.js.map +1 -0
  215. package/dist/schema/state/sqlite/query-builder/api.d.ts +7 -7
  216. package/dist/schema/state/sqlite/query-builder/api.d.ts.map +1 -1
  217. package/dist/schema/state/sqlite/query-builder/astToSql.d.ts.map +1 -1
  218. package/dist/schema/state/sqlite/query-builder/astToSql.js +27 -23
  219. package/dist/schema/state/sqlite/query-builder/astToSql.js.map +1 -1
  220. package/dist/schema/state/sqlite/query-builder/impl.d.ts +3 -1
  221. package/dist/schema/state/sqlite/query-builder/impl.d.ts.map +1 -1
  222. package/dist/schema/state/sqlite/query-builder/impl.js +16 -14
  223. package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -1
  224. package/dist/schema/state/sqlite/query-builder/impl.test.js +362 -596
  225. package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -1
  226. package/dist/schema/state/sqlite/schema-helpers.js +1 -1
  227. package/dist/schema/state/sqlite/schema-helpers.js.map +1 -1
  228. package/dist/schema/state/sqlite/system-tables/eventlog-tables.d.ts +102 -134
  229. package/dist/schema/state/sqlite/system-tables/eventlog-tables.d.ts.map +1 -1
  230. package/dist/schema/state/sqlite/system-tables/eventlog-tables.js +2 -2
  231. package/dist/schema/state/sqlite/system-tables/eventlog-tables.js.map +1 -1
  232. package/dist/schema/state/sqlite/system-tables/state-tables.d.ts +328 -106
  233. package/dist/schema/state/sqlite/system-tables/state-tables.d.ts.map +1 -1
  234. package/dist/schema/state/sqlite/system-tables/state-tables.js +33 -1
  235. package/dist/schema/state/sqlite/system-tables/state-tables.js.map +1 -1
  236. package/dist/schema/state/sqlite/table-def.d.ts +16 -19
  237. package/dist/schema/state/sqlite/table-def.d.ts.map +1 -1
  238. package/dist/schema/state/sqlite/table-def.js +53 -3
  239. package/dist/schema/state/sqlite/table-def.js.map +1 -1
  240. package/dist/schema/state/sqlite/table-def.test.js +153 -36
  241. package/dist/schema/state/sqlite/table-def.test.js.map +1 -1
  242. package/dist/schema/unknown-events.d.ts.map +1 -1
  243. package/dist/schema/unknown-events.js +2 -1
  244. package/dist/schema/unknown-events.js.map +1 -1
  245. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js +2 -2
  246. package/dist/session-id-symbol.d.ts +29 -0
  247. package/dist/session-id-symbol.d.ts.map +1 -0
  248. package/dist/session-id-symbol.js +44 -0
  249. package/dist/session-id-symbol.js.map +1 -0
  250. package/dist/sql-queries/sql-queries.d.ts.map +1 -1
  251. package/dist/sql-queries/sql-queries.js +8 -10
  252. package/dist/sql-queries/sql-queries.js.map +1 -1
  253. package/dist/sql-queries/types.d.ts +6 -7
  254. package/dist/sql-queries/types.d.ts.map +1 -1
  255. package/dist/sql-queries/types.js.map +1 -1
  256. package/dist/sqlite-db-helper.d.ts +21 -1
  257. package/dist/sqlite-db-helper.d.ts.map +1 -1
  258. package/dist/sqlite-db-helper.js +37 -2
  259. package/dist/sqlite-db-helper.js.map +1 -1
  260. package/dist/sqlite-types.d.ts +3 -6
  261. package/dist/sqlite-types.d.ts.map +1 -1
  262. package/dist/sqlite-types.js +3 -3
  263. package/dist/sqlite-types.js.map +1 -1
  264. package/dist/sync/ClientSessionSyncProcessor.d.ts +38 -16
  265. package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
  266. package/dist/sync/ClientSessionSyncProcessor.js +196 -66
  267. package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
  268. package/dist/sync/errors.d.ts +12 -18
  269. package/dist/sync/errors.d.ts.map +1 -1
  270. package/dist/sync/errors.js +2 -2
  271. package/dist/sync/errors.js.map +1 -1
  272. package/dist/sync/mock-sync-backend.d.ts +2 -3
  273. package/dist/sync/mock-sync-backend.d.ts.map +1 -1
  274. package/dist/sync/mock-sync-backend.js +54 -33
  275. package/dist/sync/mock-sync-backend.js.map +1 -1
  276. package/dist/sync/mock-sync-backend.test.d.ts +2 -0
  277. package/dist/sync/mock-sync-backend.test.d.ts.map +1 -0
  278. package/dist/sync/mock-sync-backend.test.js +49 -0
  279. package/dist/sync/mock-sync-backend.test.js.map +1 -0
  280. package/dist/sync/next/history-dag-common.d.ts +4 -0
  281. package/dist/sync/next/history-dag-common.d.ts.map +1 -1
  282. package/dist/sync/next/history-dag-common.js +52 -31
  283. package/dist/sync/next/history-dag-common.js.map +1 -1
  284. package/dist/sync/next/history-dag.d.ts.map +1 -1
  285. package/dist/sync/next/history-dag.js +2 -1
  286. package/dist/sync/next/history-dag.js.map +1 -1
  287. package/dist/sync/next/test/compact-events.calculator.test.js +2 -2
  288. package/dist/sync/next/test/event-fixtures.d.ts +7 -7
  289. package/dist/sync/next/test/event-fixtures.js +1 -1
  290. package/dist/sync/next/test/event-fixtures.js.map +1 -1
  291. package/dist/sync/next/test/history-dag-common.test.d.ts +2 -0
  292. package/dist/sync/next/test/history-dag-common.test.d.ts.map +1 -0
  293. package/dist/sync/next/test/history-dag-common.test.js +73 -0
  294. package/dist/sync/next/test/history-dag-common.test.js.map +1 -0
  295. package/dist/sync/sync-backend-kv.d.ts.map +1 -1
  296. package/dist/sync/sync-backend-kv.js +4 -2
  297. package/dist/sync/sync-backend-kv.js.map +1 -1
  298. package/dist/sync/sync-backend.d.ts +15 -15
  299. package/dist/sync/sync-backend.d.ts.map +1 -1
  300. package/dist/sync/sync-backend.js +9 -5
  301. package/dist/sync/sync-backend.js.map +1 -1
  302. package/dist/sync/sync.d.ts +1 -1
  303. package/dist/sync/sync.d.ts.map +1 -1
  304. package/dist/sync/syncstate.d.ts +97 -173
  305. package/dist/sync/syncstate.d.ts.map +1 -1
  306. package/dist/sync/syncstate.js +34 -37
  307. package/dist/sync/syncstate.js.map +1 -1
  308. package/dist/sync/syncstate.test.js +100 -61
  309. package/dist/sync/syncstate.test.js.map +1 -1
  310. package/dist/sync/transport-chunking.d.ts +15 -16
  311. package/dist/sync/transport-chunking.d.ts.map +1 -1
  312. package/dist/sync/transport-chunking.js +23 -32
  313. package/dist/sync/transport-chunking.js.map +1 -1
  314. package/dist/util.d.ts +11 -4
  315. package/dist/util.d.ts.map +1 -1
  316. package/dist/util.js +19 -2
  317. package/dist/util.js.map +1 -1
  318. package/dist/version.d.ts.map +1 -1
  319. package/dist/version.js.map +1 -1
  320. package/package.json +19 -37
  321. package/src/ClientSessionLeaderThreadProxy.ts +1 -1
  322. package/src/MaterializationJournal.ts +184 -0
  323. package/src/StateHead.ts +80 -0
  324. package/src/WorkerTransportError.ts +4 -4
  325. package/src/__tests__/fixture.ts +3 -3
  326. package/src/adapter-types.ts +24 -61
  327. package/src/debug-info.ts +50 -70
  328. package/src/defs.ts +2 -2
  329. package/src/devtools/devtools-compatibility.test.ts +1 -0
  330. package/src/devtools/devtools-messages-client-session.ts +56 -65
  331. package/src/devtools/devtools-messages-common.ts +12 -11
  332. package/src/devtools/devtools-messages-leader.ts +71 -69
  333. package/src/devtools/devtools-sessioninfo.ts +13 -11
  334. package/src/devtools/mod.ts +4 -5
  335. package/src/errors.ts +46 -34
  336. package/src/index.ts +8 -1
  337. package/src/leader-thread/LeaderSyncProcessor.ts +794 -691
  338. package/src/leader-thread/RejectedPushError.ts +40 -27
  339. package/src/leader-thread/connection.ts +12 -8
  340. package/src/leader-thread/eventlog.ts +7 -7
  341. package/src/leader-thread/leader-worker-devtools.ts +37 -19
  342. package/src/leader-thread/make-leader-thread-layer.test.ts +7 -7
  343. package/src/leader-thread/make-leader-thread-layer.ts +56 -53
  344. package/src/leader-thread/materialize-event.ts +13 -8
  345. package/src/leader-thread/recreate-db.ts +24 -59
  346. package/src/leader-thread/shutdown-channel.ts +3 -14
  347. package/src/leader-thread/stream-events.ts +104 -101
  348. package/src/leader-thread/types.ts +24 -62
  349. package/src/logging.ts +5 -52
  350. package/src/make-client-session.ts +6 -6
  351. package/src/materializer-helper.ts +8 -37
  352. package/src/otel.ts +5 -14
  353. package/src/rematerialize-from-eventlog.ts +97 -94
  354. package/src/schema/EventDef/define.test.ts +28 -0
  355. package/src/schema/EventDef/define.ts +20 -19
  356. package/src/schema/EventDef/deprecated.test.ts +1 -8
  357. package/src/schema/EventDef/deprecated.ts +17 -20
  358. package/src/schema/EventDef/event-def.ts +2 -4
  359. package/src/schema/EventSequenceNumber/client.ts +8 -9
  360. package/src/schema/EventSequenceNumber/global.ts +1 -1
  361. package/src/schema/EventSequenceNumber.test.ts +5 -5
  362. package/src/schema/LiveStoreEvent/client.test.ts +17 -4
  363. package/src/schema/LiveStoreEvent/client.ts +36 -35
  364. package/src/schema/LiveStoreEvent/for-event-def.ts +7 -7
  365. package/src/schema/LiveStoreEvent/global.ts +1 -1
  366. package/src/schema/LiveStoreEvent/input.ts +6 -6
  367. package/src/schema/mod.ts +1 -0
  368. package/src/schema/schema.ts +3 -2
  369. package/src/schema/state/sqlite/client-document-def.test.ts +32 -13
  370. package/src/schema/state/sqlite/client-document-def.ts +95 -80
  371. package/src/schema/state/sqlite/column-annotations.test.ts +26 -45
  372. package/src/schema/state/sqlite/column-annotations.ts +26 -30
  373. package/src/schema/state/sqlite/column-def.test.ts +132 -77
  374. package/src/schema/state/sqlite/column-def.ts +72 -37
  375. package/src/schema/state/sqlite/column-spec.test.ts +2 -2
  376. package/src/schema/state/sqlite/column-spec.ts +3 -2
  377. package/src/schema/state/sqlite/db-schema/ast/sqlite.ts +15 -5
  378. package/src/schema/state/sqlite/db-schema/dsl/__snapshots__/field-defs.test.ts.snap +123 -63
  379. package/src/schema/state/sqlite/db-schema/dsl/field-defs.test.ts +35 -16
  380. package/src/schema/state/sqlite/db-schema/dsl/field-defs.ts +25 -31
  381. package/src/schema/state/sqlite/db-schema/dsl/mod.ts +35 -21
  382. package/src/schema/state/sqlite/mod.ts +2 -4
  383. package/src/schema/state/sqlite/persistence.ts +11 -0
  384. package/src/schema/state/sqlite/query-builder/api.ts +9 -9
  385. package/src/schema/state/sqlite/query-builder/astToSql.ts +31 -26
  386. package/src/schema/state/sqlite/query-builder/impl.test.ts +433 -669
  387. package/src/schema/state/sqlite/query-builder/impl.ts +19 -15
  388. package/src/schema/state/sqlite/schema-helpers.ts +1 -1
  389. package/src/schema/state/sqlite/system-tables/eventlog-tables.ts +2 -2
  390. package/src/schema/state/sqlite/system-tables/state-tables.ts +41 -1
  391. package/src/schema/state/sqlite/table-def.test.ts +204 -66
  392. package/src/schema/state/sqlite/table-def.ts +96 -45
  393. package/src/schema/unknown-events.ts +3 -2
  394. package/src/schema-management/__tests__/migrations-autoincrement-quoting.test.ts +2 -2
  395. package/src/session-id-symbol.ts +59 -0
  396. package/src/sql-queries/sql-queries.ts +8 -12
  397. package/src/sql-queries/types.ts +6 -7
  398. package/src/sqlite-db-helper.ts +64 -2
  399. package/src/sqlite-types.ts +5 -8
  400. package/src/sync/ClientSessionSyncProcessor.ts +303 -119
  401. package/src/sync/errors.ts +14 -12
  402. package/src/sync/mock-sync-backend.test.ts +78 -0
  403. package/src/sync/mock-sync-backend.ts +93 -47
  404. package/src/sync/next/history-dag-common.ts +60 -34
  405. package/src/sync/next/history-dag.ts +4 -1
  406. package/src/sync/next/test/compact-events.calculator.test.ts +2 -2
  407. package/src/sync/next/test/event-fixtures.ts +1 -1
  408. package/src/sync/next/test/history-dag-common.test.ts +87 -0
  409. package/src/sync/sync-backend-kv.ts +4 -2
  410. package/src/sync/sync-backend.ts +15 -15
  411. package/src/sync/sync.ts +1 -1
  412. package/src/sync/syncstate.test.ts +191 -140
  413. package/src/sync/syncstate.ts +63 -53
  414. package/src/sync/transport-chunking.ts +34 -39
  415. package/src/util.ts +18 -9
  416. package/src/version.ts +1 -2
  417. package/dist/sql-queries/misc.d.ts +0 -2
  418. package/dist/sql-queries/misc.d.ts.map +0 -1
  419. package/dist/sql-queries/misc.js +0 -2
  420. package/dist/sql-queries/misc.js.map +0 -1
  421. package/src/sql-queries/misc.ts +0 -2
@@ -7,6 +7,7 @@ import { logDeprecationWarnings } from '../schema/EventDef/deprecated.ts'
7
7
  import type { LiveStoreSchema } from '../schema/mod.ts'
8
8
  import { EventSequenceNumber, resolveEventDef, SystemTables, UNKNOWN_EVENT_SCHEMA_HASH } from '../schema/mod.ts'
9
9
  import { insertRow } from '../sql-queries/index.ts'
10
+ import * as StateHead from '../StateHead.ts'
10
11
  import { sql } from '../util.ts'
11
12
  import { execSql, execSqlPrepared } from './connection.ts'
12
13
  import * as Eventlog from './eventlog.ts'
@@ -21,8 +22,9 @@ export const makeMaterializeEvent = ({
21
22
  schema: LiveStoreSchema
22
23
  dbState: SqliteDb
23
24
  dbEventlog: SqliteDb
24
- }): Effect.Effect<MaterializeEvent> =>
25
+ }): Effect.Effect<MaterializeEvent, never, StateHead.StateHead> =>
25
26
  Effect.gen(function* () {
27
+ const stateHead = yield* StateHead.StateHead
26
28
  const eventDefSchemaHashMap = new Map(
27
29
  // TODO Running `Schema.hash` can be a bottleneck for larger schemas. There is an opportunity to run this
28
30
  // at build time and lookup the pre-computed hash at runtime.
@@ -53,6 +55,7 @@ export const makeMaterializeEvent = ({
53
55
  )
54
56
  }
55
57
 
58
+ yield* stateHead.set(eventEncoded.seqNum)
56
59
  dbState.debug.head = eventEncoded.seqNum
57
60
 
58
61
  return {
@@ -123,6 +126,7 @@ export const makeMaterializeEvent = ({
123
126
  },
124
127
  }),
125
128
  )
129
+ yield* stateHead.set(eventEncoded.seqNum)
126
130
 
127
131
  // console.groupEnd()
128
132
 
@@ -144,13 +148,14 @@ export const makeMaterializeEvent = ({
144
148
  }
145
149
 
146
150
  return {
147
- sessionChangeset: changeset !== undefined
148
- ? {
149
- _tag: 'sessionChangeset' as const,
150
- data: changeset,
151
- debug: LS_DEV === true ? execArgsArr : null,
152
- }
153
- : { _tag: 'no-op' as const },
151
+ sessionChangeset:
152
+ changeset !== undefined
153
+ ? {
154
+ _tag: 'sessionChangeset' as const,
155
+ data: changeset,
156
+ debug: LS_DEV === true ? execArgsArr : null,
157
+ }
158
+ : { _tag: 'no-op' as const },
154
159
  hash: materializerHash,
155
160
  }
156
161
  }).pipe(
@@ -1,11 +1,9 @@
1
- import { casesHandled } from '@livestore/utils'
2
1
  import { Effect, Queue } from '@livestore/utils/effect'
3
2
 
4
3
  import type { MigrationsReport } from '../defs.ts'
5
4
  import {
6
5
  type BootStatus,
7
6
  type MaterializeError,
8
- type MigrationHooks,
9
7
  migrateDb,
10
8
  rematerializeFromEventlog,
11
9
  type SqliteDb,
@@ -30,8 +28,7 @@ export const recreateDb = ({
30
28
  materializeEvent: MaterializeEvent
31
29
  }): Effect.Effect<{ migrationsReport: MigrationsReport }, UnknownError | MaterializeError | SqliteError> =>
32
30
  Effect.gen(function* () {
33
- const migrationOptions = schema.state.sqlite.migrations
34
- let migrationsReport: MigrationsReport = { migrations: [] }
31
+ const hooks = schema.state.sqlite.migrations.hooks
35
32
 
36
33
  yield* Effect.addFinalizer(
37
34
  Effect.fn('recreateDb:finalizer')(function* (ex) {
@@ -46,61 +43,29 @@ export const recreateDb = ({
46
43
  const tmpDb = dbState
47
44
  yield* configureConnection(tmpDb, { foreignKeys: true })
48
45
 
49
- const initDb = (hooks: Partial<MigrationHooks> | undefined) =>
50
- Effect.gen(function* () {
51
- yield* Effect.tryAll(() => hooks?.init?.(tmpDb)).pipe(UnknownError.mapToUnknownError)
52
-
53
- const migrationsReport = yield* migrateDb({
54
- db: tmpDb,
55
- schema,
56
- onProgress: ({ done, total }) =>
57
- Queue.offer(bootStatusQueue, { stage: 'migrating', progress: { done, total } }),
58
- })
59
-
60
- yield* Effect.tryAll(() => hooks?.pre?.(tmpDb)).pipe(UnknownError.mapToUnknownError)
61
-
62
- return { migrationsReport, tmpDb }
63
- })
64
-
65
- switch (migrationOptions.strategy) {
66
- case 'auto': {
67
- const hooks = migrationOptions.hooks
68
- const initResult = yield* initDb(hooks)
69
-
70
- migrationsReport = initResult.migrationsReport
71
-
72
- yield* rematerializeFromEventlog({
73
- // db: initResult.tmpDb,
74
- dbEventlog,
75
- schema,
76
- materializeEvent,
77
- onProgress: ({ done, total }) =>
78
- Queue.offer(bootStatusQueue, { stage: 'rehydrating', progress: { done, total } }),
79
- })
80
-
81
- yield* Effect.tryAll(() => hooks?.post?.(initResult.tmpDb)).pipe(UnknownError.mapToUnknownError)
82
-
83
- break
84
- }
85
- case 'manual': {
86
- const oldDbData = dbState.export()
87
-
88
- migrationsReport = { migrations: [] }
89
-
90
- const newDbData = yield* Effect.tryAll(() => migrationOptions.migrate(oldDbData)).pipe(
91
- UnknownError.mapToUnknownError,
92
- )
93
-
94
- tmpDb.import(newDbData)
95
-
96
- // TODO validate schema
97
-
98
- break
99
- }
100
- default: {
101
- casesHandled(migrationOptions)
102
- }
103
- }
46
+ // @effect-diagnostics-next-line anyUnknownInErrorContext:off -- user hook errors are immediately normalized to LiveStore UnknownError
47
+ yield* Effect.trySyncOrPromiseOrEffect(() => hooks?.init?.(tmpDb)).pipe(UnknownError.mapToUnknownError)
48
+
49
+ const migrationsReport = yield* migrateDb({
50
+ db: tmpDb,
51
+ schema,
52
+ onProgress: ({ done, total }) => Queue.offer(bootStatusQueue, { stage: 'migrating', progress: { done, total } }),
53
+ })
54
+
55
+ // @effect-diagnostics-next-line anyUnknownInErrorContext:off -- user hook errors are immediately normalized to LiveStore UnknownError
56
+ yield* Effect.trySyncOrPromiseOrEffect(() => hooks?.pre?.(tmpDb)).pipe(UnknownError.mapToUnknownError)
57
+
58
+ yield* rematerializeFromEventlog({
59
+ // db: tmpDb,
60
+ dbEventlog,
61
+ schema,
62
+ materializeEvent,
63
+ onProgress: ({ done, total }) =>
64
+ Queue.offer(bootStatusQueue, { stage: 'rehydrating', progress: { done, total } }),
65
+ })
66
+
67
+ // @effect-diagnostics-next-line anyUnknownInErrorContext:off -- user hook errors are immediately normalized to LiveStore UnknownError
68
+ yield* Effect.trySyncOrPromiseOrEffect(() => hooks?.post?.(tmpDb)).pipe(UnknownError.mapToUnknownError)
104
69
 
105
70
  // TODO bring back
106
71
  // Import the temporary in-memory database into the persistent database
@@ -1,19 +1,8 @@
1
- import type { WebChannel } from '@livestore/utils/effect'
2
- import { Schema } from '@livestore/utils/effect'
1
+ import { type WebChannel, Schema } from '@livestore/utils/effect'
3
2
 
4
- import {
5
- BackendIdMismatchError,
6
- IntentionalShutdownCause,
7
- MaterializeError,
8
- UnknownError,
9
- } from '../index.ts'
3
+ import { BackendIdMismatchError, IntentionalShutdownCause, MaterializeError, UnknownError } from '../index.ts'
10
4
 
11
- export class All extends Schema.Union(
12
- IntentionalShutdownCause,
13
- UnknownError,
14
- BackendIdMismatchError,
15
- MaterializeError,
16
- ) {}
5
+ export const All = Schema.Union([IntentionalShutdownCause, UnknownError, BackendIdMismatchError, MaterializeError])
17
6
 
18
7
  /**
19
8
  * Used internally by an adapter to shutdown gracefully.
@@ -1,5 +1,4 @@
1
- import type { Subscribable } from '@livestore/utils/effect'
2
- import { Chunk, Effect, Option, Queue, Stream } from '@livestore/utils/effect'
1
+ import { type Subscribable, Effect, Option, Queue, Stream } from '@livestore/utils/effect'
3
2
 
4
3
  import { EventSequenceNumber, type LiveStoreEvent } from '../schema/mod.ts'
5
4
  import type * as SyncState from '../sync/syncstate.ts'
@@ -15,19 +14,17 @@ import type { LeaderSqliteDb, StreamEventsOptions } from './types.ts'
15
14
  * The batch size is set to 100 by default as this was meassured to provide the
16
15
  * best performance and 1000 as the upper limit.
17
16
  *
18
- * Adapters that call this helper:
17
+ * Adapters that call this helper include:
19
18
  * - `packages/@livestore/adapter-web/src/in-memory/in-memory-adapter.ts`
20
19
  * - `packages/@livestore/adapter-web/src/web-worker/leader-worker/make-leader-worker.ts`
21
- * - `packages/@livestore/adapter-node/src/client-session/adapter.ts`
22
- * - `packages/@livestore/adapter-node/src/make-leader-worker.ts`
23
20
  * - `packages/@livestore/adapter-cloudflare/src/make-adapter.ts`
21
+ * - external leader-thread adapters
24
22
  *
25
23
  * Each caller resolves dependencies inside the leader scope before invoking this helper,
26
24
  * so the stream stays environment-agnostic and does not leak `LeaderThreadCtx` into runtime
27
25
  * entry points such as `Store.eventsStream`.
28
26
  *
29
27
  * Test files:
30
- * Unit: `tests/package-common/src/leader-thread/stream-events.test.ts`
31
28
  * Integration: `packages/@livestore/livestore/src/store/store-eventstream.test.ts`
32
29
  * Performance: `tests/perf-eventlog/tests/suites/event-streaming.test.ts`
33
30
  *
@@ -48,7 +45,7 @@ import type { LeaderSqliteDb, StreamEventsOptions } from './types.ts'
48
45
  * Fetch plans into sink and decompose into windows
49
46
  * https://gist.github.com/slashv/a8f55f50121c080937f42e44b4039ac8
50
47
  *
51
- * Mailbox and Latch approach (suggestion by Tim Smart)
48
+ * Queue and Latch approach (suggestion by Tim Smart)
52
49
  * https://gist.github.com/slashv/d6b12395c85415bf0d3363372a1636c3
53
50
  */
54
51
  export const streamEventsWithSyncState = ({
@@ -63,7 +60,7 @@ export const streamEventsWithSyncState = ({
63
60
  const initialCursor = options.since ?? EventSequenceNumber.Client.ROOT
64
61
  const batchSize = options.batchSize ?? 100
65
62
 
66
- return Stream.unwrapScoped(
63
+ return Stream.unwrap(
67
64
  Effect.gen(function* () {
68
65
  /**
69
66
  * Single-element Queue allows suspending the event stream until head
@@ -101,105 +98,111 @@ export const streamEventsWithSyncState = ({
101
98
  Effect.forkScoped,
102
99
  )
103
100
 
104
- return Stream.paginateChunkEffect(
105
- { cursor: initialCursor, head: EventSequenceNumber.Client.ROOT },
106
- ({ cursor, head }) =>
107
- Effect.gen(function* () {
108
- /**
109
- * Early check guards agains:
110
- * since === until : Prevent empty query
111
- * since > until : Incorrectly inverted interval
112
- */
113
- if (
114
- options.until !== undefined &&
115
- EventSequenceNumber.Client.isGreaterThanOrEqual(cursor, options.until) === true
116
- ) {
117
- return [Chunk.empty(), Option.none()]
118
- }
101
+ return Stream.paginate({ cursor: initialCursor, head: EventSequenceNumber.Client.ROOT }, ({ cursor, head }) =>
102
+ Effect.gen(function* () {
103
+ /**
104
+ * Early check guards agains:
105
+ * since === until : Prevent empty query
106
+ * since > until : Incorrectly inverted interval
107
+ */
108
+ if (
109
+ options.until !== undefined &&
110
+ EventSequenceNumber.Client.isGreaterThanOrEqual(cursor, options.until) === true
111
+ ) {
112
+ const done: readonly [
113
+ ReadonlyArray<LiveStoreEvent.Client.Encoded>,
114
+ Option.Option<{
115
+ cursor: EventSequenceNumber.Client.Composite
116
+ head: EventSequenceNumber.Client.Composite
117
+ }>,
118
+ ] = [[], Option.none()]
119
+ return done
120
+ }
121
+
122
+ /**
123
+ * There are two scenarios where we take the next head from the headQueue:
124
+ *
125
+ * 1. We need to wait for the head to advance
126
+ * The Stream suspends until a new head is available on the headQueue
127
+ *
128
+ * 2. Head has advanced during itteration
129
+ * While itterating towards the lastest head taken from the headQueue
130
+ * in increments of batchSize it's possible the head could have
131
+ * advanced. This leads to a suboptimal amount of queries. Therefor we
132
+ * check if the headQueue is full which tells us that there's a new
133
+ * head available to take. Example:
134
+ *
135
+ * batchSize: 2
136
+ *
137
+ * --> head at: e3
138
+ * First query: e0 -> e2 (two events)
139
+ * --> head advances to: e4
140
+ * Second query: e2 -> e3 (one event but we could have taken 2)
141
+ * --> Take the new head of e4
142
+ * Third query: e3 -> e4 (unnecessary third query)
143
+ *
144
+ *
145
+ * To define the target, which will be used as the temporary until
146
+ * marker for the eventlog query, we select the lowest of three possible values:
147
+ *
148
+ * hardStop: A user supplied until marker
149
+ * current cursor + batchSize: A batchSize step towards the latest head from headQueue
150
+ * nextHead: The latest head from headQueue
151
+ */
152
+ const waitForHead = EventSequenceNumber.Client.isGreaterThanOrEqual(cursor, head)
153
+ const maybeHead =
154
+ waitForHead === true
155
+ ? yield* Queue.take(headQueue).pipe(Effect.map(Option.some))
156
+ : yield* Queue.poll(headQueue)
157
+ const nextHead = Option.getOrElse(maybeHead, () => head)
158
+ const hardStop = options.until?.global ?? Number.POSITIVE_INFINITY
159
+ const target = EventSequenceNumber.Client.Composite.make({
160
+ global: Math.min(hardStop, cursor.global + batchSize, nextHead.global),
161
+ client: EventSequenceNumber.Client.DEFAULT,
162
+ })
119
163
 
120
- /**
121
- * There are two scenarios where we take the next head from the headQueue:
122
- *
123
- * 1. We need to wait for the head to advance
124
- * The Stream suspends until a new head is available on the headQueue
125
- *
126
- * 2. Head has advanced during itteration
127
- * While itterating towards the lastest head taken from the headQueue
128
- * in increments of batchSize it's possible the head could have
129
- * advanced. This leads to a suboptimal amount of queries. Therefor we
130
- * check if the headQueue is full which tells us that there's a new
131
- * head available to take. Example:
132
- *
133
- * batchSize: 2
134
- *
135
- * --> head at: e3
136
- * First query: e0 -> e2 (two events)
137
- * --> head advances to: e4
138
- * Second query: e2 -> e3 (one event but we could have taken 2)
139
- * --> Take the new head of e4
140
- * Third query: e3 -> e4 (unnecessary third query)
141
- *
142
- *
143
- * To define the target, which will be used as the temporary until
144
- * marker for the eventlog query, we select the lowest of three possible values:
145
- *
146
- * hardStop: A user supplied until marker
147
- * current cursor + batchSize: A batchSize step towards the latest head from headQueue
148
- * nextHead: The latest head from headQueue
149
- */
150
- const waitForHead = EventSequenceNumber.Client.isGreaterThanOrEqual(cursor, head)
151
- const maybeHead =
152
- waitForHead === true
153
- ? yield* Queue.take(headQueue).pipe(Effect.map(Option.some))
154
- : yield* Queue.poll(headQueue)
155
- const nextHead = Option.getOrElse(maybeHead, () => head)
156
- const hardStop = options.until?.global ?? Number.POSITIVE_INFINITY
157
- const target = EventSequenceNumber.Client.Composite.make({
158
- global: Math.min(hardStop, cursor.global + batchSize, nextHead.global),
159
- client: EventSequenceNumber.Client.DEFAULT,
160
- })
164
+ /**
165
+ * Eventlog.getEventsFromEventlog returns a batch from each query
166
+ * which is what we emit at each itteration.
167
+ */
168
+ const events = yield* Eventlog.getEventsFromEventlog({
169
+ dbEventlog,
170
+ options: {
171
+ ...options,
172
+ since: cursor,
173
+ until: target,
174
+ },
175
+ })
161
176
 
162
- /**
163
- * Eventlog.getEventsFromEventlog returns a Chunk from each
164
- * query which is what we emit at each itteration.
165
- */
166
- const chunk = yield* Eventlog.getEventsFromEventlog({
167
- dbEventlog,
168
- options: {
169
- ...options,
170
- since: cursor,
171
- until: target,
172
- },
173
- })
177
+ /**
178
+ * We construct the state for the following itteration of the stream
179
+ * loop by setting the current target as the since cursor and pass
180
+ * along the latest head.
181
+ *
182
+ * If we have the reached the user supplied until marker we signal the
183
+ * finalization of the stream by passing Option.none() instead.
184
+ */
185
+ const reachedUntil =
186
+ options.until !== undefined && EventSequenceNumber.Client.isGreaterThanOrEqual(target, options.until)
174
187
 
175
- /**
176
- * We construct the state for the following itteration of the stream
177
- * loop by setting the current target as the since cursor and pass
178
- * along the latest head.
179
- *
180
- * If we have the reached the user supplied until marker we signal the
181
- * finalization of the stream by passing Option.none() instead.
182
- */
183
- const reachedUntil =
184
- options.until !== undefined && EventSequenceNumber.Client.isGreaterThanOrEqual(target, options.until)
188
+ const nextState: Option.Option<{
189
+ cursor: EventSequenceNumber.Client.Composite
190
+ head: EventSequenceNumber.Client.Composite
191
+ }> = reachedUntil === true ? Option.none() : Option.some({ cursor: target, head: nextHead })
185
192
 
186
- const nextState: Option.Option<{
187
- cursor: EventSequenceNumber.Client.Composite
188
- head: EventSequenceNumber.Client.Composite
189
- }> = reachedUntil === true ? Option.none() : Option.some({ cursor: target, head: nextHead })
193
+ const spanAttributes = {
194
+ 'livestore.streamEvents.cursor.global': cursor.global,
195
+ 'livestore.streamEvents.target.global': target.global,
196
+ 'livestore.streamEvents.batchSize': batchSize,
197
+ 'livestore.streamEvents.waitedForHead': waitForHead,
198
+ }
190
199
 
191
- const spanAttributes = {
192
- 'livestore.streamEvents.cursor.global': cursor.global,
193
- 'livestore.streamEvents.target.global': target.global,
194
- 'livestore.streamEvents.batchSize': batchSize,
195
- 'livestore.streamEvents.waitedForHead': waitForHead,
196
- }
200
+ const result: readonly [ReadonlyArray<LiveStoreEvent.Client.Encoded>, typeof nextState] = [events, nextState]
197
201
 
198
- return yield* Effect.succeed<[Chunk.Chunk<LiveStoreEvent.Client.Encoded>, typeof nextState]>([
199
- chunk,
200
- nextState,
201
- ]).pipe(Effect.withSpan('@livestore/common:streamEvents:segment', { attributes: spanAttributes }))
202
- }),
202
+ return yield* Effect.succeed(result).pipe(
203
+ Effect.withSpan('@livestore/common:streamEvents:segment', { attributes: spanAttributes }),
204
+ )
205
+ }),
203
206
  )
204
207
  }),
205
208
  )
@@ -1,15 +1,17 @@
1
- import type {
2
- Deferred,
3
- Effect,
4
- HttpClient,
5
- Option,
6
- Queue,
7
- Scope,
8
- Stream,
9
- Subscribable,
10
- SubscriptionRef,
1
+ import {
2
+ type Deferred,
3
+ type Effect,
4
+ type HttpClient,
5
+ type Latch,
6
+ type Option,
7
+ type Queue,
8
+ type Scope,
9
+ type Stream,
10
+ type Subscribable,
11
+ type SubscriptionRef,
12
+ Context,
13
+ Schema,
11
14
  } from '@livestore/utils/effect'
12
- import { Context, Schema } from '@livestore/utils/effect'
13
15
  import type { MeshNode } from '@livestore/webmesh'
14
16
 
15
17
  import type { MigrationsReport } from '../defs.ts'
@@ -22,11 +24,10 @@ import type {
22
24
  SqliteDb,
23
25
  SyncBackend,
24
26
  UnknownError,
25
- UnknownEventError,
26
27
  } from '../index.ts'
27
- import type { RejectedPushError } from './RejectedPushError.ts'
28
28
  import { EventSequenceNumber, type LiveStoreEvent, type LiveStoreSchema } from '../schema/mod.ts'
29
29
  import type * as SyncState from '../sync/syncstate.ts'
30
+ import type * as LeaderSyncProcessor from './LeaderSyncProcessor.ts'
30
31
  import type { ShutdownChannel } from './shutdown-channel.ts'
31
32
 
32
33
  export type ShutdownState = 'running' | 'shutting-down'
@@ -35,17 +36,17 @@ export const InitialSyncOptionsSkip = Schema.TaggedStruct('Skip', {})
35
36
  export type InitialSyncOptionsSkip = typeof InitialSyncOptionsSkip.Type
36
37
 
37
38
  export const InitialSyncOptionsBlocking = Schema.TaggedStruct('Blocking', {
38
- timeout: Schema.Union(Schema.DurationFromMillis, Schema.Number),
39
+ timeout: Schema.Union([Schema.DurationFromMillis, Schema.Finite]),
39
40
  })
40
41
 
41
42
  export type InitialSyncOptionsBlocking = typeof InitialSyncOptionsBlocking.Type
42
43
 
43
- export const InitialSyncOptions = Schema.Union(InitialSyncOptionsSkip, InitialSyncOptionsBlocking)
44
+ export const InitialSyncOptions = Schema.Union([InitialSyncOptionsSkip, InitialSyncOptionsBlocking])
44
45
  export type InitialSyncOptions = typeof InitialSyncOptions.Type
45
46
 
46
47
  export type InitialSyncInfo = Option.Option<{
47
48
  eventSequenceNumber: EventSequenceNumber.Global.Type
48
- metadata: Option.Option<Schema.JsonValue>
49
+ metadata: Option.Option<Schema.Json>
49
50
  }>
50
51
 
51
52
  // export type InitialSetup =
@@ -75,16 +76,16 @@ export type DevtoolsOptions =
75
76
  export type DevtoolsContext =
76
77
  | {
77
78
  enabled: true
78
- // syncBackendPullLatch: Effect.Latch
79
- // syncBackendPushLatch: Effect.Latch
80
- syncBackendLatch: Effect.Latch
79
+ // syncBackendPullLatch: Latch.Latch
80
+ // syncBackendPushLatch: Latch.Latch
81
+ syncBackendLatch: Latch.Latch
81
82
  syncBackendLatchState: SubscriptionRef.SubscriptionRef<{ latchClosed: boolean }>
82
83
  }
83
84
  | {
84
85
  enabled: false
85
86
  }
86
87
 
87
- export class LeaderThreadCtx extends Context.Tag('LeaderThreadCtx')<
88
+ export class LeaderThreadCtx extends Context.Service<
88
89
  LeaderThreadCtx,
89
90
  {
90
91
  schema: LiveStoreSchema
@@ -100,7 +101,7 @@ export class LeaderThreadCtx extends Context.Tag('LeaderThreadCtx')<
100
101
  eventSchema: LiveStoreEvent.ForEventDef.ForRecord<any>
101
102
  devtools: DevtoolsContext
102
103
  syncBackend: SyncBackend.SyncBackend | undefined
103
- syncProcessor: LeaderSyncProcessor
104
+ syncProcessor: LeaderSyncProcessor.Service
104
105
  materializeEvent: MaterializeEvent
105
106
  initialState: {
106
107
  leaderHead: EventSequenceNumber.Client.Composite
@@ -114,7 +115,7 @@ export class LeaderThreadCtx extends Context.Tag('LeaderThreadCtx')<
114
115
  extraIncomingMessagesQueue: Queue.Queue<Devtools.Leader.MessageToApp>
115
116
  networkStatus: Subscribable.Subscribable<SyncBackend.NetworkStatus>
116
117
  }
117
- >() {}
118
+ >()('LeaderThreadCtx') {}
118
119
 
119
120
  export type MaterializeEvent = (
120
121
  eventEncoded: LiveStoreEvent.Client.EncodedWithMeta,
@@ -144,7 +145,7 @@ export const StreamEventsOptionsFields = {
144
145
  filter: Schema.optional(Schema.Array(Schema.String)),
145
146
  clientIds: Schema.optional(Schema.Array(Schema.String)),
146
147
  sessionIds: Schema.optional(Schema.Array(Schema.String)),
147
- batchSize: Schema.optional(Schema.Int.pipe(Schema.between(1, STREAM_EVENTS_BATCH_SIZE_MAX))),
148
+ batchSize: Schema.optional(Schema.Int.check(Schema.isBetween({ minimum: 1, maximum: STREAM_EVENTS_BATCH_SIZE_MAX }))),
148
149
  includeClientOnly: Schema.optional(Schema.Boolean),
149
150
  } as const
150
151
 
@@ -182,42 +183,3 @@ export interface StreamEventsOptions {
182
183
  */
183
184
  includeClientOnly?: boolean
184
185
  }
185
-
186
- export interface LeaderSyncProcessor {
187
- /** Used by client sessions to subscribe to upstream sync state changes */
188
- pull: (args: {
189
- cursor: EventSequenceNumber.Client.Composite
190
- }) => Stream.Stream<{ payload: typeof SyncState.PayloadUpstream.Type }>
191
- /** The `pullQueue` API can be used instead of `pull` when more convenient */
192
- pullQueue: (args: {
193
- cursor: EventSequenceNumber.Client.Composite
194
- }) => Effect.Effect<Queue.Queue<{ payload: typeof SyncState.PayloadUpstream.Type }>, never, Scope.Scope>
195
-
196
- /** Used by client sessions to push events to the leader thread */
197
- push: (
198
- /** `batch` needs to follow the same rules as `batch` in `SyncBackend.push` */
199
- batch: ReadonlyArray<LiveStoreEvent.Client.EncodedWithMeta>,
200
- options?: {
201
- /**
202
- * If true, the effect will only finish when the local push has been processed (i.e. succeeded or was rejected).
203
- * `true` doesn't mean the events have been pushed to the sync backend.
204
- * @default false
205
- */
206
- waitForProcessing?: boolean
207
- },
208
- ) => Effect.Effect<void, RejectedPushError>
209
-
210
- /** Currently only used by devtools which don't provide their own event numbers */
211
- pushPartial: (args: {
212
- event: LiveStoreEvent.Input.Encoded
213
- clientId: string
214
- sessionId: string
215
- }) => Effect.Effect<void, UnknownEventError>
216
-
217
- boot: Effect.Effect<
218
- { initialLeaderHead: EventSequenceNumber.Client.Composite },
219
- never,
220
- LeaderThreadCtx | Scope.Scope | HttpClient.HttpClient
221
- >
222
- syncState: Subscribable.Subscribable<SyncState.SyncState>
223
- }
package/src/logging.ts CHANGED
@@ -1,62 +1,15 @@
1
- import { isDevEnv } from '@livestore/utils'
2
- import { Effect, type Layer, Logger, LogLevel } from '@livestore/utils/effect'
1
+ import type { Layer, LogLevel } from '@livestore/utils/effect'
3
2
 
4
3
  /**
5
- * Optional Effect logger configuration that LiveStore entry points accept.
4
+ * Optional Effect logger configuration accepted by LiveStore entry points.
6
5
  *
7
- * When provided, `logger` replaces the default pretty logger for the runtime.
8
- * Use `logLevel` to control verbosity. Set to `LogLevel.None` to disable logging
6
+ * When provided, `logger` replaces the default logger for the runtime.
7
+ * Use `logLevel` to control verbosity. Set to `"None"` to disable logging
9
8
  * entirely while keeping the same logger implementation.
10
9
  */
11
- export type WithLoggerOptions = {
10
+ export type LoggerOptions = {
12
11
  /** Optional Effect logger layer to control logging output. */
13
12
  logger?: Layer.Layer<never> | undefined
14
13
  /** Optional minimum log level for the runtime. */
15
14
  logLevel?: LogLevel.LogLevel | undefined
16
15
  }
17
-
18
- /**
19
- * Common defaults for resolving a logger configuration.
20
- * - `threadName` is used by the default pretty logger when `logger` is not provided.
21
- * - `mode` selects pretty logger mode (e.g. 'browser' for web workers).
22
- * - `defaultLogLevel` is used when `logLevel` is not provided.
23
- */
24
- export type LoggerDefaults = {
25
- threadName?: string
26
- mode?: 'tty' | 'browser'
27
- defaultLogLevel?: LogLevel.LogLevel
28
- /** Optional default logger layer to use when `config.logger` is not provided. */
29
- defaultLogger?: Layer.Layer<never>
30
- }
31
-
32
- /**
33
- * Resolve the logger layer to provide to the Effect runtime.
34
- */
35
- export const resolveLoggerLayer = (config?: WithLoggerOptions, defaults?: LoggerDefaults): Layer.Layer<never> => {
36
- if (config?.logger !== undefined) return config.logger
37
- if (defaults?.defaultLogger !== undefined) return defaults.defaultLogger
38
- const threadName = defaults?.threadName ?? 'livestore'
39
- const mode = defaults?.mode
40
- return Logger.prettyWithThread(threadName, mode !== undefined ? { mode } : {})
41
- }
42
-
43
- /**
44
- * Resolve the minimum log level, falling back to `defaults.defaultLogLevel` then `LogLevel.Debug`.
45
- */
46
- export const resolveLogLevel = (config?: WithLoggerOptions, defaults?: LoggerDefaults): LogLevel.LogLevel => {
47
- if (config?.logLevel !== undefined) return config.logLevel
48
- if (defaults?.defaultLogLevel !== undefined) return defaults.defaultLogLevel
49
- return isDevEnv() === true ? LogLevel.Debug : LogLevel.Info
50
- }
51
-
52
- /**
53
- * Wrap an effect by applying the resolved minimum log level and providing the resolved logger layer.
54
- */
55
- export const withLoggerConfig = <TEnv, TError, TOut>(
56
- config?: WithLoggerOptions,
57
- defaults?: LoggerDefaults,
58
- ): ((effect: Effect.Effect<TOut, TError, TEnv>) => Effect.Effect<TOut, TError, TEnv>) => {
59
- const level = resolveLogLevel(config, defaults)
60
- const layer = resolveLoggerLayer(config, defaults)
61
- return (effect) => effect.pipe(Logger.withMinimumLogLevel(level), Effect.provide(layer))
62
- }