@livestore/common 0.4.0-dev.8 → 0.4.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 (518) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/ClientSessionLeaderThreadProxy.d.ts +27 -12
  3. package/dist/ClientSessionLeaderThreadProxy.d.ts.map +1 -1
  4. package/dist/ClientSessionLeaderThreadProxy.js.map +1 -1
  5. package/dist/WorkerTransportError.d.ts +11 -0
  6. package/dist/WorkerTransportError.d.ts.map +1 -0
  7. package/dist/WorkerTransportError.js +11 -0
  8. package/dist/WorkerTransportError.js.map +1 -0
  9. package/dist/adapter-types.d.ts +37 -7
  10. package/dist/adapter-types.d.ts.map +1 -1
  11. package/dist/adapter-types.js +27 -1
  12. package/dist/adapter-types.js.map +1 -1
  13. package/dist/bounded-collections.d.ts.map +1 -1
  14. package/dist/bounded-collections.js +6 -4
  15. package/dist/bounded-collections.js.map +1 -1
  16. package/dist/debug-info.d.ts.map +1 -1
  17. package/dist/debug-info.js +33 -6
  18. package/dist/debug-info.js.map +1 -1
  19. package/dist/devtools/devtools-compatibility.test.d.ts +2 -0
  20. package/dist/devtools/devtools-compatibility.test.d.ts.map +1 -0
  21. package/dist/devtools/devtools-compatibility.test.js +15 -0
  22. package/dist/devtools/devtools-compatibility.test.js.map +1 -0
  23. package/dist/devtools/devtools-messages-client-session.d.ts +55 -24
  24. package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -1
  25. package/dist/devtools/devtools-messages-client-session.js +22 -5
  26. package/dist/devtools/devtools-messages-client-session.js.map +1 -1
  27. package/dist/devtools/devtools-messages-common.d.ts +11 -14
  28. package/dist/devtools/devtools-messages-common.d.ts.map +1 -1
  29. package/dist/devtools/devtools-messages-common.js +7 -9
  30. package/dist/devtools/devtools-messages-common.js.map +1 -1
  31. package/dist/devtools/devtools-messages-leader.d.ts +65 -30
  32. package/dist/devtools/devtools-messages-leader.d.ts.map +1 -1
  33. package/dist/devtools/devtools-messages-leader.js +29 -11
  34. package/dist/devtools/devtools-messages-leader.js.map +1 -1
  35. package/dist/devtools/devtools-sessioninfo.d.ts +14 -2
  36. package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -1
  37. package/dist/devtools/devtools-sessioninfo.js +7 -4
  38. package/dist/devtools/devtools-sessioninfo.js.map +1 -1
  39. package/dist/devtools/mod.d.ts +13 -2
  40. package/dist/devtools/mod.d.ts.map +1 -1
  41. package/dist/devtools/mod.js +10 -3
  42. package/dist/devtools/mod.js.map +1 -1
  43. package/dist/errors.d.ts +48 -18
  44. package/dist/errors.d.ts.map +1 -1
  45. package/dist/errors.js +20 -12
  46. package/dist/errors.js.map +1 -1
  47. package/dist/index.d.ts +4 -1
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +4 -1
  50. package/dist/index.js.map +1 -1
  51. package/dist/leader-thread/LeaderSyncProcessor.d.ts +53 -6
  52. package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
  53. package/dist/leader-thread/LeaderSyncProcessor.js +325 -257
  54. package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
  55. package/dist/leader-thread/RejectedPushError.d.ts +107 -0
  56. package/dist/leader-thread/RejectedPushError.d.ts.map +1 -0
  57. package/dist/leader-thread/RejectedPushError.js +78 -0
  58. package/dist/leader-thread/RejectedPushError.js.map +1 -0
  59. package/dist/leader-thread/connection.js +1 -1
  60. package/dist/leader-thread/connection.js.map +1 -1
  61. package/dist/leader-thread/eventlog.d.ts +19 -14
  62. package/dist/leader-thread/eventlog.d.ts.map +1 -1
  63. package/dist/leader-thread/eventlog.js +78 -18
  64. package/dist/leader-thread/eventlog.js.map +1 -1
  65. package/dist/leader-thread/leader-worker-devtools.d.ts +1 -2
  66. package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
  67. package/dist/leader-thread/leader-worker-devtools.js +90 -58
  68. package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
  69. package/dist/leader-thread/make-leader-thread-layer.d.ts +15 -7
  70. package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
  71. package/dist/leader-thread/make-leader-thread-layer.js +49 -17
  72. package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
  73. package/dist/leader-thread/make-leader-thread-layer.test.d.ts +2 -0
  74. package/dist/leader-thread/make-leader-thread-layer.test.d.ts.map +1 -0
  75. package/dist/leader-thread/make-leader-thread-layer.test.js +32 -0
  76. package/dist/leader-thread/make-leader-thread-layer.test.js.map +1 -0
  77. package/dist/leader-thread/materialize-event.d.ts +1 -1
  78. package/dist/leader-thread/materialize-event.d.ts.map +1 -1
  79. package/dist/leader-thread/materialize-event.js +28 -9
  80. package/dist/leader-thread/materialize-event.js.map +1 -1
  81. package/dist/leader-thread/mod.d.ts +1 -0
  82. package/dist/leader-thread/mod.d.ts.map +1 -1
  83. package/dist/leader-thread/mod.js +1 -0
  84. package/dist/leader-thread/mod.js.map +1 -1
  85. package/dist/leader-thread/recreate-db.d.ts +2 -2
  86. package/dist/leader-thread/recreate-db.d.ts.map +1 -1
  87. package/dist/leader-thread/recreate-db.js +6 -6
  88. package/dist/leader-thread/recreate-db.js.map +1 -1
  89. package/dist/leader-thread/shutdown-channel.d.ts +2 -2
  90. package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
  91. package/dist/leader-thread/shutdown-channel.js +2 -2
  92. package/dist/leader-thread/shutdown-channel.js.map +1 -1
  93. package/dist/leader-thread/stream-events.d.ts +56 -0
  94. package/dist/leader-thread/stream-events.d.ts.map +1 -0
  95. package/dist/leader-thread/stream-events.js +167 -0
  96. package/dist/leader-thread/stream-events.js.map +1 -0
  97. package/dist/leader-thread/types.d.ts +95 -17
  98. package/dist/leader-thread/types.d.ts.map +1 -1
  99. package/dist/leader-thread/types.js +13 -0
  100. package/dist/leader-thread/types.js.map +1 -1
  101. package/dist/logging.d.ts +40 -0
  102. package/dist/logging.d.ts.map +1 -0
  103. package/dist/logging.js +33 -0
  104. package/dist/logging.js.map +1 -0
  105. package/dist/make-client-session.d.ts +5 -3
  106. package/dist/make-client-session.d.ts.map +1 -1
  107. package/dist/make-client-session.js +7 -4
  108. package/dist/make-client-session.js.map +1 -1
  109. package/dist/materializer-helper.d.ts +6 -6
  110. package/dist/materializer-helper.d.ts.map +1 -1
  111. package/dist/materializer-helper.js +18 -8
  112. package/dist/materializer-helper.js.map +1 -1
  113. package/dist/otel.d.ts +2 -1
  114. package/dist/otel.d.ts.map +1 -1
  115. package/dist/otel.js +7 -2
  116. package/dist/otel.js.map +1 -1
  117. package/dist/rematerialize-from-eventlog.d.ts +3 -3
  118. package/dist/rematerialize-from-eventlog.d.ts.map +1 -1
  119. package/dist/rematerialize-from-eventlog.js +40 -29
  120. package/dist/rematerialize-from-eventlog.js.map +1 -1
  121. package/dist/schema/EventDef/define.d.ts +161 -0
  122. package/dist/schema/EventDef/define.d.ts.map +1 -0
  123. package/dist/schema/EventDef/define.js +140 -0
  124. package/dist/schema/EventDef/define.js.map +1 -0
  125. package/dist/schema/EventDef/deprecated.d.ts +99 -0
  126. package/dist/schema/EventDef/deprecated.d.ts.map +1 -0
  127. package/dist/schema/EventDef/deprecated.js +144 -0
  128. package/dist/schema/EventDef/deprecated.js.map +1 -0
  129. package/dist/schema/EventDef/deprecated.test.d.ts +2 -0
  130. package/dist/schema/EventDef/deprecated.test.d.ts.map +1 -0
  131. package/dist/schema/EventDef/deprecated.test.js +95 -0
  132. package/dist/schema/EventDef/deprecated.test.js.map +1 -0
  133. package/dist/schema/EventDef/event-def.d.ts +110 -0
  134. package/dist/schema/EventDef/event-def.d.ts.map +1 -0
  135. package/dist/schema/EventDef/event-def.js +2 -0
  136. package/dist/schema/EventDef/event-def.js.map +1 -0
  137. package/dist/schema/EventDef/facts.d.ts +118 -0
  138. package/dist/schema/EventDef/facts.d.ts.map +1 -0
  139. package/dist/schema/EventDef/facts.js +53 -0
  140. package/dist/schema/EventDef/facts.js.map +1 -0
  141. package/dist/schema/EventDef/materializer.d.ts +155 -0
  142. package/dist/schema/EventDef/materializer.d.ts.map +1 -0
  143. package/dist/schema/EventDef/materializer.js +83 -0
  144. package/dist/schema/EventDef/materializer.js.map +1 -0
  145. package/dist/schema/EventDef/mod.d.ts +6 -0
  146. package/dist/schema/EventDef/mod.d.ts.map +1 -0
  147. package/dist/schema/EventDef/mod.js +6 -0
  148. package/dist/schema/EventDef/mod.js.map +1 -0
  149. package/dist/schema/EventSequenceNumber/client.d.ts +136 -0
  150. package/dist/schema/EventSequenceNumber/client.d.ts.map +1 -0
  151. package/dist/schema/EventSequenceNumber/client.js +193 -0
  152. package/dist/schema/EventSequenceNumber/client.js.map +1 -0
  153. package/dist/schema/EventSequenceNumber/global.d.ts +15 -0
  154. package/dist/schema/EventSequenceNumber/global.d.ts.map +1 -0
  155. package/dist/schema/EventSequenceNumber/global.js +14 -0
  156. package/dist/schema/EventSequenceNumber/global.js.map +1 -0
  157. package/dist/schema/EventSequenceNumber/mod.d.ts +37 -0
  158. package/dist/schema/EventSequenceNumber/mod.d.ts.map +1 -0
  159. package/dist/schema/EventSequenceNumber/mod.js +37 -0
  160. package/dist/schema/EventSequenceNumber/mod.js.map +1 -0
  161. package/dist/schema/EventSequenceNumber.test.js +44 -44
  162. package/dist/schema/EventSequenceNumber.test.js.map +1 -1
  163. package/dist/schema/{LiveStoreEvent.d.ts → LiveStoreEvent/client.d.ts} +102 -111
  164. package/dist/schema/LiveStoreEvent/client.d.ts.map +1 -0
  165. package/dist/schema/LiveStoreEvent/client.js +176 -0
  166. package/dist/schema/LiveStoreEvent/client.js.map +1 -0
  167. package/dist/schema/LiveStoreEvent/client.test.d.ts +2 -0
  168. package/dist/schema/LiveStoreEvent/client.test.d.ts.map +1 -0
  169. package/dist/schema/LiveStoreEvent/client.test.js +111 -0
  170. package/dist/schema/LiveStoreEvent/client.test.js.map +1 -0
  171. package/dist/schema/LiveStoreEvent/for-event-def.d.ts +52 -0
  172. package/dist/schema/LiveStoreEvent/for-event-def.d.ts.map +1 -0
  173. package/dist/schema/LiveStoreEvent/for-event-def.js +2 -0
  174. package/dist/schema/LiveStoreEvent/for-event-def.js.map +1 -0
  175. package/dist/schema/LiveStoreEvent/global.d.ts +36 -0
  176. package/dist/schema/LiveStoreEvent/global.d.ts.map +1 -0
  177. package/dist/schema/LiveStoreEvent/global.js +31 -0
  178. package/dist/schema/LiveStoreEvent/global.js.map +1 -0
  179. package/dist/schema/LiveStoreEvent/input.d.ts +46 -0
  180. package/dist/schema/LiveStoreEvent/input.d.ts.map +1 -0
  181. package/dist/schema/LiveStoreEvent/input.js +26 -0
  182. package/dist/schema/LiveStoreEvent/input.js.map +1 -0
  183. package/dist/schema/LiveStoreEvent/mod.d.ts +5 -0
  184. package/dist/schema/LiveStoreEvent/mod.d.ts.map +1 -0
  185. package/dist/schema/LiveStoreEvent/mod.js +5 -0
  186. package/dist/schema/LiveStoreEvent/mod.js.map +1 -0
  187. package/dist/schema/events.d.ts +1 -1
  188. package/dist/schema/events.d.ts.map +1 -1
  189. package/dist/schema/events.js +1 -1
  190. package/dist/schema/events.js.map +1 -1
  191. package/dist/schema/mod.d.ts +6 -4
  192. package/dist/schema/mod.d.ts.map +1 -1
  193. package/dist/schema/mod.js +5 -4
  194. package/dist/schema/mod.js.map +1 -1
  195. package/dist/schema/schema.d.ts +16 -1
  196. package/dist/schema/schema.d.ts.map +1 -1
  197. package/dist/schema/schema.js +32 -4
  198. package/dist/schema/schema.js.map +1 -1
  199. package/dist/schema/state/sqlite/client-document-def.d.ts +2 -1
  200. package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -1
  201. package/dist/schema/state/sqlite/client-document-def.js +36 -15
  202. package/dist/schema/state/sqlite/client-document-def.js.map +1 -1
  203. package/dist/schema/state/sqlite/client-document-def.test.js +121 -2
  204. package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -1
  205. package/dist/schema/state/sqlite/column-annotations.d.ts.map +1 -1
  206. package/dist/schema/state/sqlite/column-annotations.js +1 -1
  207. package/dist/schema/state/sqlite/column-annotations.js.map +1 -1
  208. package/dist/schema/state/sqlite/column-annotations.test.js +2 -2
  209. package/dist/schema/state/sqlite/column-annotations.test.js.map +1 -1
  210. package/dist/schema/state/sqlite/column-def.d.ts.map +1 -1
  211. package/dist/schema/state/sqlite/column-def.js +96 -47
  212. package/dist/schema/state/sqlite/column-def.js.map +1 -1
  213. package/dist/schema/state/sqlite/column-def.test.js +51 -12
  214. package/dist/schema/state/sqlite/column-def.test.js.map +1 -1
  215. package/dist/schema/state/sqlite/column-spec.d.ts.map +1 -1
  216. package/dist/schema/state/sqlite/column-spec.js +30 -12
  217. package/dist/schema/state/sqlite/column-spec.js.map +1 -1
  218. package/dist/schema/state/sqlite/column-spec.test.js +24 -15
  219. package/dist/schema/state/sqlite/column-spec.test.js.map +1 -1
  220. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js +2 -2
  221. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js.map +1 -1
  222. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts +16 -10
  223. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts.map +1 -1
  224. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js +15 -4
  225. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js.map +1 -1
  226. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js +1 -1
  227. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js.map +1 -1
  228. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts +1 -1
  229. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts.map +1 -1
  230. package/dist/schema/state/sqlite/db-schema/dsl/mod.js +1 -1
  231. package/dist/schema/state/sqlite/db-schema/dsl/mod.js.map +1 -1
  232. package/dist/schema/state/sqlite/mod.d.ts +2 -2
  233. package/dist/schema/state/sqlite/mod.d.ts.map +1 -1
  234. package/dist/schema/state/sqlite/mod.js +5 -7
  235. package/dist/schema/state/sqlite/mod.js.map +1 -1
  236. package/dist/schema/state/sqlite/query-builder/api.d.ts +51 -22
  237. package/dist/schema/state/sqlite/query-builder/api.d.ts.map +1 -1
  238. package/dist/schema/state/sqlite/query-builder/astToSql.d.ts.map +1 -1
  239. package/dist/schema/state/sqlite/query-builder/astToSql.js +99 -22
  240. package/dist/schema/state/sqlite/query-builder/astToSql.js.map +1 -1
  241. package/dist/schema/state/sqlite/query-builder/impl.d.ts +1 -1
  242. package/dist/schema/state/sqlite/query-builder/impl.d.ts.map +1 -1
  243. package/dist/schema/state/sqlite/query-builder/impl.js +28 -15
  244. package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -1
  245. package/dist/schema/state/sqlite/query-builder/impl.test.js +231 -93
  246. package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -1
  247. package/dist/schema/state/sqlite/schema-helpers.d.ts +2 -2
  248. package/dist/schema/state/sqlite/schema-helpers.d.ts.map +1 -1
  249. package/dist/schema/state/sqlite/schema-helpers.js +24 -14
  250. package/dist/schema/state/sqlite/schema-helpers.js.map +1 -1
  251. package/dist/schema/state/sqlite/schema-helpers.test.d.ts +2 -0
  252. package/dist/schema/state/sqlite/schema-helpers.test.d.ts.map +1 -0
  253. package/dist/schema/state/sqlite/schema-helpers.test.js +36 -0
  254. package/dist/schema/state/sqlite/schema-helpers.test.js.map +1 -0
  255. package/dist/schema/state/sqlite/{system-tables.d.ts → system-tables/eventlog-tables.d.ts} +21 -450
  256. package/dist/schema/state/sqlite/system-tables/eventlog-tables.d.ts.map +1 -0
  257. package/dist/schema/state/sqlite/system-tables/eventlog-tables.js +54 -0
  258. package/dist/schema/state/sqlite/system-tables/eventlog-tables.js.map +1 -0
  259. package/dist/schema/state/sqlite/system-tables/mod.d.ts +3 -0
  260. package/dist/schema/state/sqlite/system-tables/mod.d.ts.map +1 -0
  261. package/dist/schema/state/sqlite/system-tables/mod.js +3 -0
  262. package/dist/schema/state/sqlite/system-tables/mod.js.map +1 -0
  263. package/dist/schema/state/sqlite/system-tables/state-tables.d.ts +456 -0
  264. package/dist/schema/state/sqlite/system-tables/state-tables.d.ts.map +1 -0
  265. package/dist/schema/state/sqlite/system-tables/state-tables.js +55 -0
  266. package/dist/schema/state/sqlite/system-tables/state-tables.js.map +1 -0
  267. package/dist/schema/state/sqlite/table-def.d.ts +5 -3
  268. package/dist/schema/state/sqlite/table-def.d.ts.map +1 -1
  269. package/dist/schema/state/sqlite/table-def.js +1 -1
  270. package/dist/schema/state/sqlite/table-def.js.map +1 -1
  271. package/dist/schema/state/sqlite/table-def.test.js +92 -3
  272. package/dist/schema/state/sqlite/table-def.test.js.map +1 -1
  273. package/dist/schema/unknown-events.d.ts +47 -0
  274. package/dist/schema/unknown-events.d.ts.map +1 -0
  275. package/dist/schema/unknown-events.js +69 -0
  276. package/dist/schema/unknown-events.js.map +1 -0
  277. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.d.ts +2 -0
  278. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.d.ts.map +1 -0
  279. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js +73 -0
  280. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js.map +1 -0
  281. package/dist/schema-management/common.js +2 -2
  282. package/dist/schema-management/common.js.map +1 -1
  283. package/dist/schema-management/migrations.d.ts +32 -2
  284. package/dist/schema-management/migrations.d.ts.map +1 -1
  285. package/dist/schema-management/migrations.js +38 -6
  286. package/dist/schema-management/migrations.js.map +1 -1
  287. package/dist/schema-management/validate-schema.d.ts +3 -3
  288. package/dist/schema-management/validate-schema.d.ts.map +1 -1
  289. package/dist/schema-management/validate-schema.js +2 -2
  290. package/dist/schema-management/validate-schema.js.map +1 -1
  291. package/dist/sql-queries/sql-queries.d.ts.map +1 -1
  292. package/dist/sql-queries/sql-queries.js +18 -6
  293. package/dist/sql-queries/sql-queries.js.map +1 -1
  294. package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
  295. package/dist/sql-queries/sql-query-builder.js.map +1 -1
  296. package/dist/sqlite-db-helper.js +3 -3
  297. package/dist/sqlite-db-helper.js.map +1 -1
  298. package/dist/sqlite-types.d.ts +5 -5
  299. package/dist/sqlite-types.d.ts.map +1 -1
  300. package/dist/sqlite-types.js.map +1 -1
  301. package/dist/sync/ClientSessionSyncProcessor.d.ts +12 -12
  302. package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
  303. package/dist/sync/ClientSessionSyncProcessor.js +99 -114
  304. package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
  305. package/dist/sync/errors.d.ts +0 -33
  306. package/dist/sync/errors.d.ts.map +1 -1
  307. package/dist/sync/errors.js +5 -22
  308. package/dist/sync/errors.js.map +1 -1
  309. package/dist/sync/index.d.ts +2 -0
  310. package/dist/sync/index.d.ts.map +1 -1
  311. package/dist/sync/index.js +2 -0
  312. package/dist/sync/index.js.map +1 -1
  313. package/dist/sync/mock-sync-backend.d.ts +10 -8
  314. package/dist/sync/mock-sync-backend.d.ts.map +1 -1
  315. package/dist/sync/mock-sync-backend.js +71 -69
  316. package/dist/sync/mock-sync-backend.js.map +1 -1
  317. package/dist/sync/next/compact-events.d.ts.map +1 -1
  318. package/dist/sync/next/compact-events.js +11 -12
  319. package/dist/sync/next/compact-events.js.map +1 -1
  320. package/dist/sync/next/facts.d.ts +5 -5
  321. package/dist/sync/next/facts.d.ts.map +1 -1
  322. package/dist/sync/next/facts.js +7 -8
  323. package/dist/sync/next/facts.js.map +1 -1
  324. package/dist/sync/next/history-dag-common.d.ts +54 -15
  325. package/dist/sync/next/history-dag-common.d.ts.map +1 -1
  326. package/dist/sync/next/history-dag-common.js +198 -9
  327. package/dist/sync/next/history-dag-common.js.map +1 -1
  328. package/dist/sync/next/history-dag.d.ts.map +1 -1
  329. package/dist/sync/next/history-dag.js +11 -11
  330. package/dist/sync/next/history-dag.js.map +1 -1
  331. package/dist/sync/next/rebase-events.d.ts +5 -5
  332. package/dist/sync/next/rebase-events.d.ts.map +1 -1
  333. package/dist/sync/next/rebase-events.js +6 -6
  334. package/dist/sync/next/rebase-events.js.map +1 -1
  335. package/dist/sync/next/test/compact-events.calculator.test.js +2 -2
  336. package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
  337. package/dist/sync/next/test/compact-events.test.d.ts.map +1 -1
  338. package/dist/sync/next/test/compact-events.test.js +2 -2
  339. package/dist/sync/next/test/compact-events.test.js.map +1 -1
  340. package/dist/sync/next/test/event-fixtures.d.ts +2 -2
  341. package/dist/sync/next/test/event-fixtures.d.ts.map +1 -1
  342. package/dist/sync/next/test/event-fixtures.js +11 -11
  343. package/dist/sync/next/test/event-fixtures.js.map +1 -1
  344. package/dist/sync/sync-backend-kv.d.ts +3 -3
  345. package/dist/sync/sync-backend-kv.d.ts.map +1 -1
  346. package/dist/sync/sync-backend-kv.js +3 -3
  347. package/dist/sync/sync-backend-kv.js.map +1 -1
  348. package/dist/sync/sync-backend.d.ts +33 -13
  349. package/dist/sync/sync-backend.d.ts.map +1 -1
  350. package/dist/sync/sync-backend.js +38 -1
  351. package/dist/sync/sync-backend.js.map +1 -1
  352. package/dist/sync/sync.d.ts +23 -2
  353. package/dist/sync/sync.d.ts.map +1 -1
  354. package/dist/sync/syncstate.d.ts +55 -55
  355. package/dist/sync/syncstate.d.ts.map +1 -1
  356. package/dist/sync/syncstate.js +80 -98
  357. package/dist/sync/syncstate.js.map +1 -1
  358. package/dist/sync/syncstate.test.js +221 -132
  359. package/dist/sync/syncstate.test.js.map +1 -1
  360. package/dist/sync/transport-chunking.d.ts +36 -0
  361. package/dist/sync/transport-chunking.d.ts.map +1 -0
  362. package/dist/sync/transport-chunking.js +56 -0
  363. package/dist/sync/transport-chunking.js.map +1 -0
  364. package/dist/sync/validate-push-payload.d.ts +2 -2
  365. package/dist/sync/validate-push-payload.d.ts.map +1 -1
  366. package/dist/sync/validate-push-payload.js +4 -6
  367. package/dist/sync/validate-push-payload.js.map +1 -1
  368. package/dist/testing/event-factory.d.ts +68 -0
  369. package/dist/testing/event-factory.d.ts.map +1 -0
  370. package/dist/testing/event-factory.js +78 -0
  371. package/dist/testing/event-factory.js.map +1 -0
  372. package/dist/testing/mod.d.ts +2 -0
  373. package/dist/testing/mod.d.ts.map +1 -0
  374. package/dist/testing/mod.js +2 -0
  375. package/dist/testing/mod.js.map +1 -0
  376. package/dist/util.js +2 -2
  377. package/dist/util.js.map +1 -1
  378. package/dist/version.d.ts +24 -5
  379. package/dist/version.d.ts.map +1 -1
  380. package/dist/version.js +25 -8
  381. package/dist/version.js.map +1 -1
  382. package/package.json +69 -16
  383. package/src/ClientSessionLeaderThreadProxy.ts +27 -12
  384. package/src/WorkerTransportError.ts +12 -0
  385. package/src/adapter-types.ts +50 -7
  386. package/src/bounded-collections.ts +6 -5
  387. package/src/debug-info.ts +37 -6
  388. package/src/devtools/devtools-compatibility.test.ts +18 -0
  389. package/src/devtools/devtools-messages-client-session.ts +22 -4
  390. package/src/devtools/devtools-messages-common.ts +7 -12
  391. package/src/devtools/devtools-messages-leader.ts +29 -10
  392. package/src/devtools/devtools-sessioninfo.ts +8 -5
  393. package/src/devtools/mod.ts +11 -2
  394. package/src/errors.ts +32 -24
  395. package/src/index.ts +4 -1
  396. package/src/leader-thread/LeaderSyncProcessor.ts +523 -373
  397. package/src/leader-thread/RejectedPushError.ts +106 -0
  398. package/src/leader-thread/connection.ts +1 -1
  399. package/src/leader-thread/eventlog.ts +112 -39
  400. package/src/leader-thread/leader-worker-devtools.ts +201 -120
  401. package/src/leader-thread/make-leader-thread-layer.test.ts +44 -0
  402. package/src/leader-thread/make-leader-thread-layer.ts +125 -40
  403. package/src/leader-thread/materialize-event.ts +40 -10
  404. package/src/leader-thread/mod.ts +1 -0
  405. package/src/leader-thread/recreate-db.ts +7 -7
  406. package/src/leader-thread/shutdown-channel.ts +4 -8
  407. package/src/leader-thread/stream-events.ts +206 -0
  408. package/src/leader-thread/types.ts +68 -18
  409. package/src/logging.ts +62 -0
  410. package/src/make-client-session.ts +11 -5
  411. package/src/materializer-helper.ts +27 -16
  412. package/src/otel.ts +13 -2
  413. package/src/rematerialize-from-eventlog.ts +61 -51
  414. package/src/schema/EventDef/define.ts +217 -0
  415. package/src/schema/EventDef/deprecated.test.ts +129 -0
  416. package/src/schema/EventDef/deprecated.ts +175 -0
  417. package/src/schema/EventDef/event-def.ts +125 -0
  418. package/src/schema/EventDef/facts.ts +135 -0
  419. package/src/schema/EventDef/materializer.ts +172 -0
  420. package/src/schema/EventDef/mod.ts +5 -0
  421. package/src/schema/EventSequenceNumber/client.ts +257 -0
  422. package/src/schema/EventSequenceNumber/global.ts +19 -0
  423. package/src/schema/EventSequenceNumber/mod.ts +37 -0
  424. package/src/schema/EventSequenceNumber.test.ts +72 -53
  425. package/src/schema/LiveStoreEvent/client.test.ts +129 -0
  426. package/src/schema/LiveStoreEvent/client.ts +235 -0
  427. package/src/schema/LiveStoreEvent/for-event-def.ts +60 -0
  428. package/src/schema/LiveStoreEvent/global.ts +45 -0
  429. package/src/schema/LiveStoreEvent/input.ts +63 -0
  430. package/src/schema/LiveStoreEvent/mod.ts +4 -0
  431. package/src/schema/events.ts +1 -1
  432. package/src/schema/mod.ts +6 -4
  433. package/src/schema/schema.ts +46 -5
  434. package/src/schema/state/sqlite/client-document-def.test.ts +144 -5
  435. package/src/schema/state/sqlite/client-document-def.ts +47 -34
  436. package/src/schema/state/sqlite/column-annotations.test.ts +3 -2
  437. package/src/schema/state/sqlite/column-annotations.ts +2 -1
  438. package/src/schema/state/sqlite/column-def.test.ts +66 -12
  439. package/src/schema/state/sqlite/column-def.ts +119 -47
  440. package/src/schema/state/sqlite/column-spec.test.ts +32 -17
  441. package/src/schema/state/sqlite/column-spec.ts +37 -11
  442. package/src/schema/state/sqlite/db-schema/ast/sqlite.ts +2 -2
  443. package/src/schema/state/sqlite/db-schema/dsl/field-defs.test.ts +2 -1
  444. package/src/schema/state/sqlite/db-schema/dsl/field-defs.ts +41 -15
  445. package/src/schema/state/sqlite/db-schema/dsl/mod.ts +13 -19
  446. package/src/schema/state/sqlite/mod.ts +7 -8
  447. package/src/schema/state/sqlite/query-builder/api.ts +55 -17
  448. package/src/schema/state/sqlite/query-builder/astToSql.ts +110 -21
  449. package/src/schema/state/sqlite/query-builder/impl.test.ts +267 -93
  450. package/src/schema/state/sqlite/query-builder/impl.ts +26 -13
  451. package/src/schema/state/sqlite/schema-helpers.test.ts +44 -0
  452. package/src/schema/state/sqlite/schema-helpers.ts +30 -22
  453. package/src/schema/state/sqlite/system-tables/eventlog-tables.ts +64 -0
  454. package/src/schema/state/sqlite/system-tables/mod.ts +2 -0
  455. package/src/schema/state/sqlite/system-tables/state-tables.ts +69 -0
  456. package/src/schema/state/sqlite/table-def.test.ts +114 -3
  457. package/src/schema/state/sqlite/table-def.ts +16 -22
  458. package/src/schema/unknown-events.ts +131 -0
  459. package/src/schema-management/__tests__/migrations-autoincrement-quoting.test.ts +88 -0
  460. package/src/schema-management/common.ts +2 -2
  461. package/src/schema-management/migrations.ts +42 -9
  462. package/src/schema-management/validate-schema.ts +3 -3
  463. package/src/sql-queries/sql-queries.ts +18 -6
  464. package/src/sql-queries/sql-query-builder.ts +1 -0
  465. package/src/sqlite-db-helper.ts +3 -3
  466. package/src/sqlite-types.ts +6 -5
  467. package/src/sync/ClientSessionSyncProcessor.ts +152 -142
  468. package/src/sync/errors.ts +12 -24
  469. package/src/sync/index.ts +2 -0
  470. package/src/sync/mock-sync-backend.ts +146 -104
  471. package/src/sync/next/compact-events.ts +10 -11
  472. package/src/sync/next/facts.ts +13 -14
  473. package/src/sync/next/history-dag-common.ts +280 -26
  474. package/src/sync/next/history-dag.ts +17 -13
  475. package/src/sync/next/rebase-events.ts +12 -12
  476. package/src/sync/next/test/compact-events.calculator.test.ts +3 -2
  477. package/src/sync/next/test/compact-events.test.ts +4 -3
  478. package/src/sync/next/test/event-fixtures.ts +13 -13
  479. package/src/sync/sync-backend-kv.ts +4 -3
  480. package/src/sync/sync-backend.ts +66 -17
  481. package/src/sync/sync.ts +24 -2
  482. package/src/sync/syncstate.test.ts +583 -419
  483. package/src/sync/syncstate.ts +127 -122
  484. package/src/sync/transport-chunking.ts +90 -0
  485. package/src/sync/validate-push-payload.ts +6 -8
  486. package/src/testing/event-factory.ts +131 -0
  487. package/src/testing/mod.ts +1 -0
  488. package/src/util.ts +2 -2
  489. package/src/version.ts +33 -8
  490. package/dist/schema/EventDef.d.ts +0 -126
  491. package/dist/schema/EventDef.d.ts.map +0 -1
  492. package/dist/schema/EventDef.js +0 -46
  493. package/dist/schema/EventDef.js.map +0 -1
  494. package/dist/schema/EventSequenceNumber.d.ts +0 -80
  495. package/dist/schema/EventSequenceNumber.d.ts.map +0 -1
  496. package/dist/schema/EventSequenceNumber.js +0 -139
  497. package/dist/schema/EventSequenceNumber.js.map +0 -1
  498. package/dist/schema/LiveStoreEvent.d.ts.map +0 -1
  499. package/dist/schema/LiveStoreEvent.js +0 -147
  500. package/dist/schema/LiveStoreEvent.js.map +0 -1
  501. package/dist/schema/state/sqlite/system-tables.d.ts.map +0 -1
  502. package/dist/schema/state/sqlite/system-tables.js +0 -81
  503. package/dist/schema/state/sqlite/system-tables.js.map +0 -1
  504. package/dist/sync/next/graphology.d.ts +0 -8
  505. package/dist/sync/next/graphology.d.ts.map +0 -1
  506. package/dist/sync/next/graphology.js +0 -30
  507. package/dist/sync/next/graphology.js.map +0 -1
  508. package/dist/sync/next/graphology_.d.ts +0 -3
  509. package/dist/sync/next/graphology_.d.ts.map +0 -1
  510. package/dist/sync/next/graphology_.js +0 -3
  511. package/dist/sync/next/graphology_.js.map +0 -1
  512. package/src/schema/EventDef.ts +0 -222
  513. package/src/schema/EventSequenceNumber.ts +0 -199
  514. package/src/schema/LiveStoreEvent.ts +0 -286
  515. package/src/schema/state/sqlite/system-tables.ts +0 -106
  516. package/src/sync/next/ambient.d.ts +0 -3
  517. package/src/sync/next/graphology.ts +0 -41
  518. package/src/sync/next/graphology_.ts +0 -2
@@ -0,0 +1,206 @@
1
+ import type { Subscribable } from '@livestore/utils/effect'
2
+ import { Chunk, Effect, Option, Queue, Stream } from '@livestore/utils/effect'
3
+
4
+ import { EventSequenceNumber, type LiveStoreEvent } from '../schema/mod.ts'
5
+ import type * as SyncState from '../sync/syncstate.ts'
6
+ import * as Eventlog from './eventlog.ts'
7
+ import type { LeaderSqliteDb, StreamEventsOptions } from './types.ts'
8
+
9
+ /**
10
+ * Streams events for leader-thread adapters.
11
+ *
12
+ * Provides a continuous stream from the eventlog as the upstream head advances.
13
+ * When an until event is passed in the stream finalizes upon reaching it.
14
+ *
15
+ * The batch size is set to 100 by default as this was meassured to provide the
16
+ * best performance and 1000 as the upper limit.
17
+ *
18
+ * Adapters that call this helper:
19
+ * - `packages/@livestore/adapter-web/src/in-memory/in-memory-adapter.ts`
20
+ * - `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
+ * - `packages/@livestore/adapter-cloudflare/src/make-adapter.ts`
24
+ *
25
+ * Each caller resolves dependencies inside the leader scope before invoking this helper,
26
+ * so the stream stays environment-agnostic and does not leak `LeaderThreadCtx` into runtime
27
+ * entry points such as `Store.eventsStream`.
28
+ *
29
+ * Test files:
30
+ * Unit: `tests/package-common/src/leader-thread/stream-events.test.ts`
31
+ * Integration: `packages/@livestore/livestore/src/store/store-eventstream.test.ts`
32
+ * Performance: `tests/perf-eventlog/tests/suites/event-streaming.test.ts`
33
+ *
34
+ * Optimization explorations
35
+ *
36
+ * In order to alleviate the occurence of many small queries when the syncState
37
+ * is sequentially progressing quickly we have explored some time-based batching
38
+ * approaches. It remains to be determined if and when the added complexity of
39
+ * these approaches are worth the benefit. They come with some drawbacks such as
40
+ * degraded time to first event or general performance degredation for larger
41
+ * query steps. These aspects can likely be mitigated with some more work but
42
+ * that is best assessed when we have a final implementation of event streaming
43
+ * with support for session and leader level streams.
44
+ *
45
+ * Fetch plans into a Sink
46
+ * https://gist.github.com/slashv/f1223689f2d1171d2eeb60a2823f4c7c
47
+ *
48
+ * Fetch plans into sink and decompose into windows
49
+ * https://gist.github.com/slashv/a8f55f50121c080937f42e44b4039ac8
50
+ *
51
+ * Mailbox and Latch approach (suggestion by Tim Smart)
52
+ * https://gist.github.com/slashv/d6b12395c85415bf0d3363372a1636c3
53
+ */
54
+ export const streamEventsWithSyncState = ({
55
+ dbEventlog,
56
+ syncState,
57
+ options,
58
+ }: {
59
+ dbEventlog: LeaderSqliteDb
60
+ syncState: Subscribable.Subscribable<SyncState.SyncState>
61
+ options: StreamEventsOptions
62
+ }): Stream.Stream<LiveStoreEvent.Client.Encoded> => {
63
+ const initialCursor = options.since ?? EventSequenceNumber.Client.ROOT
64
+ const batchSize = options.batchSize ?? 100
65
+
66
+ return Stream.unwrapScoped(
67
+ Effect.gen(function* () {
68
+ /**
69
+ * Single-element Queue allows suspending the event stream until head
70
+ * advances because Queue.take is a suspending effect. SubscriptionRef in
71
+ * comparrison lacks a primitive for suspending a stream until a new value
72
+ * is set and would require polling.
73
+ *
74
+ * The use of a sliding Queue here is useful since it ensures only the
75
+ * lastest head from syncState is the one present on the queue without the
76
+ * need for manual substitution.
77
+ */
78
+ const headQueue = yield* Queue.sliding<EventSequenceNumber.Client.Composite>(1)
79
+
80
+ /**
81
+ * We run a separate fiber which listens to changes in syncState and
82
+ * offer the latest head to the headQueue. Keeping track of the previous
83
+ * value is done to prevent syncState changes unrelated to the
84
+ * upstreamHead triggering empty queries.
85
+ *
86
+ * When we implement support for leader and session level streams
87
+ * this will need to be adapted to support the relevant value from
88
+ * syncState that we are interested in tracking.
89
+ */
90
+ let prevGlobalHead = -1
91
+ yield* syncState.changes.pipe(
92
+ Stream.map((state) => state.upstreamHead),
93
+ Stream.filter((head) => {
94
+ if (head.global > prevGlobalHead) {
95
+ prevGlobalHead = head.global
96
+ return true
97
+ }
98
+ return false
99
+ }),
100
+ Stream.runForEach((head) => Queue.offer(headQueue, head)),
101
+ Effect.forkScoped,
102
+ )
103
+
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
+ }
119
+
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
+ })
161
+
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
+ })
174
+
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)
185
+
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 })
190
+
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
+ }
197
+
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
+ }),
203
+ )
204
+ }),
205
+ )
206
+ }
@@ -17,14 +17,15 @@ import type { MaterializeError } from '../errors.ts'
17
17
  import type {
18
18
  BootStatus,
19
19
  Devtools,
20
- LeaderAheadError,
21
20
  MakeSqliteDb,
22
21
  PersistenceInfo,
23
22
  SqliteDb,
24
23
  SyncBackend,
25
- UnexpectedError,
24
+ UnknownError,
25
+ UnknownEventError,
26
26
  } from '../index.ts'
27
- import type { EventSequenceNumber, LiveStoreEvent, LiveStoreSchema } from '../schema/mod.ts'
27
+ import type { RejectedPushError } from './RejectedPushError.ts'
28
+ import { EventSequenceNumber, type LiveStoreEvent, type LiveStoreSchema } from '../schema/mod.ts'
28
29
  import type * as SyncState from '../sync/syncstate.ts'
29
30
  import type { ShutdownChannel } from './shutdown-channel.ts'
30
31
 
@@ -43,7 +44,7 @@ export const InitialSyncOptions = Schema.Union(InitialSyncOptionsSkip, InitialSy
43
44
  export type InitialSyncOptions = typeof InitialSyncOptions.Type
44
45
 
45
46
  export type InitialSyncInfo = Option.Option<{
46
- eventSequenceNumber: EventSequenceNumber.GlobalEventSequenceNumber
47
+ eventSequenceNumber: EventSequenceNumber.Global.Type
47
48
  metadata: Option.Option<Schema.JsonValue>
48
49
  }>
49
50
 
@@ -66,7 +67,7 @@ export type DevtoolsOptions =
66
67
  persistenceInfo: PersistenceInfoPair
67
68
  mode: 'proxy' | 'direct'
68
69
  },
69
- UnexpectedError,
70
+ UnknownError,
70
71
  Scope.Scope | HttpClient.HttpClient | LeaderThreadCtx
71
72
  >
72
73
  }
@@ -96,13 +97,13 @@ export class LeaderThreadCtx extends Context.Tag('LeaderThreadCtx')<
96
97
  // TODO we should find a more elegant way to handle cases which need this ref for their implementation
97
98
  shutdownStateSubRef: SubscriptionRef.SubscriptionRef<ShutdownState>
98
99
  shutdownChannel: ShutdownChannel
99
- eventSchema: LiveStoreEvent.ForEventDefRecord<any>
100
+ eventSchema: LiveStoreEvent.ForEventDef.ForRecord<any>
100
101
  devtools: DevtoolsContext
101
102
  syncBackend: SyncBackend.SyncBackend | undefined
102
103
  syncProcessor: LeaderSyncProcessor
103
104
  materializeEvent: MaterializeEvent
104
105
  initialState: {
105
- leaderHead: EventSequenceNumber.EventSequenceNumber
106
+ leaderHead: EventSequenceNumber.Client.Composite
106
107
  migrationsReport: MigrationsReport
107
108
  }
108
109
  /**
@@ -111,11 +112,12 @@ export class LeaderThreadCtx extends Context.Tag('LeaderThreadCtx')<
111
112
  * This is currently separated from `.devtools` as it also needs to work when devtools are disabled
112
113
  */
113
114
  extraIncomingMessagesQueue: Queue.Queue<Devtools.Leader.MessageToApp>
115
+ networkStatus: Subscribable.Subscribable<SyncBackend.NetworkStatus>
114
116
  }
115
117
  >() {}
116
118
 
117
119
  export type MaterializeEvent = (
118
- eventEncoded: LiveStoreEvent.EncodedWithMeta,
120
+ eventEncoded: LiveStoreEvent.Client.EncodedWithMeta,
119
121
  options?: {
120
122
  /** Needed for rematerializeFromEventlog */
121
123
  skipEventlog?: boolean
@@ -133,20 +135,68 @@ export type InitialBlockingSyncContext = {
133
135
  update: (_: { pageInfo: SyncBackend.PullResPageInfo; processed: number }) => Effect.Effect<void>
134
136
  }
135
137
 
138
+ export const STREAM_EVENTS_BATCH_SIZE_DEFAULT = 100
139
+ export const STREAM_EVENTS_BATCH_SIZE_MAX = 1_000
140
+
141
+ export const StreamEventsOptionsFields = {
142
+ since: Schema.optional(EventSequenceNumber.Client.Composite),
143
+ until: Schema.optional(EventSequenceNumber.Client.Composite),
144
+ filter: Schema.optional(Schema.Array(Schema.String)),
145
+ clientIds: Schema.optional(Schema.Array(Schema.String)),
146
+ sessionIds: Schema.optional(Schema.Array(Schema.String)),
147
+ batchSize: Schema.optional(Schema.Int.pipe(Schema.between(1, STREAM_EVENTS_BATCH_SIZE_MAX))),
148
+ includeClientOnly: Schema.optional(Schema.Boolean),
149
+ } as const
150
+
151
+ export const StreamEventsOptionsSchema = Schema.Struct(StreamEventsOptionsFields)
152
+
153
+ export interface StreamEventsOptions {
154
+ /**
155
+ * Only include events after this logical timestamp (exclusive).
156
+ * Defaults to `EventSequenceNumber.Client.ROOT` when omitted.
157
+ */
158
+ since?: EventSequenceNumber.Client.Composite
159
+ /**
160
+ * Only include events up to this logical timestamp (inclusive).
161
+ */
162
+ until?: EventSequenceNumber.Client.Composite
163
+ /**
164
+ * Only include events of the given names.
165
+ */
166
+ filter?: ReadonlyArray<string>
167
+ /**
168
+ * Only include events from specific client identifiers.
169
+ */
170
+ clientIds?: ReadonlyArray<string>
171
+ /**
172
+ * Only include events from specific session identifiers.
173
+ */
174
+ sessionIds?: ReadonlyArray<string>
175
+ /**
176
+ * Number of events to fetch in each batch when streaming from the eventlog.
177
+ * Defaults to 100.
178
+ */
179
+ batchSize?: number
180
+ /**
181
+ * Include client-only events (i.e. events with a positive client sequence number).
182
+ */
183
+ includeClientOnly?: boolean
184
+ }
185
+
136
186
  export interface LeaderSyncProcessor {
137
187
  /** Used by client sessions to subscribe to upstream sync state changes */
138
188
  pull: (args: {
139
- cursor: EventSequenceNumber.EventSequenceNumber
140
- }) => Stream.Stream<{ payload: typeof SyncState.PayloadUpstream.Type }, UnexpectedError>
189
+ cursor: EventSequenceNumber.Client.Composite
190
+ }) => Stream.Stream<{ payload: typeof SyncState.PayloadUpstream.Type }>
141
191
  /** The `pullQueue` API can be used instead of `pull` when more convenient */
142
192
  pullQueue: (args: {
143
- cursor: EventSequenceNumber.EventSequenceNumber
144
- }) => Effect.Effect<Queue.Queue<{ payload: typeof SyncState.PayloadUpstream.Type }>, UnexpectedError, Scope.Scope>
193
+ cursor: EventSequenceNumber.Client.Composite
194
+ }) => Effect.Effect<Queue.Queue<{ payload: typeof SyncState.PayloadUpstream.Type }>, never, Scope.Scope>
145
195
 
146
196
  /** Used by client sessions to push events to the leader thread */
147
197
  push: (
148
198
  /** `batch` needs to follow the same rules as `batch` in `SyncBackend.push` */
149
- batch: ReadonlyArray<LiveStoreEvent.EncodedWithMeta>,
199
+ batch: ReadonlyArray<LiveStoreEvent.Client.EncodedWithMeta>,
150
200
  options?: {
151
201
  /**
152
202
  * If true, the effect will only finish when the local push has been processed (i.e. succeeded or was rejected).
@@ -155,18 +205,18 @@ export interface LeaderSyncProcessor {
155
205
  */
156
206
  waitForProcessing?: boolean
157
207
  },
158
- ) => Effect.Effect<void, LeaderAheadError>
208
+ ) => Effect.Effect<void, RejectedPushError>
159
209
 
160
210
  /** Currently only used by devtools which don't provide their own event numbers */
161
211
  pushPartial: (args: {
162
- event: LiveStoreEvent.PartialAnyEncoded
212
+ event: LiveStoreEvent.Input.Encoded
163
213
  clientId: string
164
214
  sessionId: string
165
- }) => Effect.Effect<void, UnexpectedError>
215
+ }) => Effect.Effect<void, UnknownEventError>
166
216
 
167
217
  boot: Effect.Effect<
168
- { initialLeaderHead: EventSequenceNumber.EventSequenceNumber },
169
- UnexpectedError,
218
+ { initialLeaderHead: EventSequenceNumber.Client.Composite },
219
+ never,
170
220
  LeaderThreadCtx | Scope.Scope | HttpClient.HttpClient
171
221
  >
172
222
  syncState: Subscribable.Subscribable<SyncState.SyncState>
package/src/logging.ts ADDED
@@ -0,0 +1,62 @@
1
+ import { isDevEnv } from '@livestore/utils'
2
+ import { Effect, type Layer, Logger, LogLevel } from '@livestore/utils/effect'
3
+
4
+ /**
5
+ * Optional Effect logger configuration that LiveStore entry points accept.
6
+ *
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
9
+ * entirely while keeping the same logger implementation.
10
+ */
11
+ export type WithLoggerOptions = {
12
+ /** Optional Effect logger layer to control logging output. */
13
+ logger?: Layer.Layer<never> | undefined
14
+ /** Optional minimum log level for the runtime. */
15
+ logLevel?: LogLevel.LogLevel | undefined
16
+ }
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
+ }
@@ -8,7 +8,7 @@ import type {
8
8
  ClientSessionLeaderThreadProxy,
9
9
  LockStatus,
10
10
  SqliteDb,
11
- UnexpectedError,
11
+ UnknownError,
12
12
  } from './adapter-types.ts'
13
13
  import * as Devtools from './devtools/mod.ts'
14
14
  import { liveStoreVersion } from './version.ts'
@@ -33,6 +33,7 @@ export const makeClientSession = <R>({
33
33
  webmeshMode,
34
34
  registerBeforeUnload,
35
35
  debugInstanceId,
36
+ origin,
36
37
  }: AdapterArgs & {
37
38
  clientId: string
38
39
  sessionId: string
@@ -43,16 +44,18 @@ export const makeClientSession = <R>({
43
44
  connectWebmeshNode: (args: {
44
45
  webmeshNode: Webmesh.MeshNode
45
46
  sessionInfo: Devtools.SessionInfo.SessionInfo
46
- }) => Effect.Effect<void, UnexpectedError, Scope.Scope | R>
47
+ }) => Effect.Effect<void, UnknownError, Scope.Scope | R>
47
48
  webmeshMode: 'direct' | 'proxy'
48
49
  registerBeforeUnload: (onBeforeUnload: () => void) => () => void
50
+ /** Browser origin of the client session; used for origin-scoped DevTools mesh channels */
51
+ origin: string | undefined
49
52
  }): Effect.Effect<ClientSession, never, Scope.Scope | R> =>
50
53
  Effect.gen(function* () {
51
- const devtools: ClientSession['devtools'] = devtoolsEnabled
54
+ const devtools: ClientSession['devtools'] = devtoolsEnabled === true
52
55
  ? { enabled: true, pullLatch: yield* Effect.makeLatch(true), pushLatch: yield* Effect.makeLatch(true) }
53
56
  : { enabled: false }
54
57
 
55
- if (devtoolsEnabled) {
58
+ if (devtoolsEnabled === true) {
56
59
  yield* Effect.gen(function* () {
57
60
  const webmeshNode = yield* Webmesh.makeMeshNode(
58
61
  Devtools.makeNodeName.client.session({ storeId, clientId, sessionId }),
@@ -67,11 +70,14 @@ export const makeClientSession = <R>({
67
70
  sessionId,
68
71
  schemaAlias,
69
72
  isLeader,
73
+ origin,
70
74
  })
71
75
 
72
76
  yield* connectWebmeshNode({ webmeshNode, sessionInfo })
73
77
 
74
- const sessionInfoBroadcastChannel = yield* Devtools.makeSessionInfoBroadcastChannel(webmeshNode)
78
+ const sessionInfoBroadcastChannel = yield* Devtools.makeSessionInfoBroadcastChannel(webmeshNode, {
79
+ origin,
80
+ })
75
81
 
76
82
  yield* Devtools.SessionInfo.provideSessionInfo({
77
83
  webChannel: sessionInfoBroadcastChannel,
@@ -3,9 +3,9 @@ import { Hash, Option, Schema } from '@livestore/utils/effect'
3
3
 
4
4
  import type { SqliteDb } from './adapter-types.ts'
5
5
  import { SessionIdSymbol } from './adapter-types.ts'
6
- import type { EventDef, Materializer, MaterializerContextQuery, MaterializerResult } from './schema/EventDef.ts'
7
- import type * as LiveStoreEvent from './schema/LiveStoreEvent.ts'
8
- import { getEventDef, type LiveStoreSchema } from './schema/schema.ts'
6
+ import type { EventDef, Materializer, MaterializerContextQuery, MaterializerResult } from './schema/EventDef/mod.ts'
7
+ import type * as LiveStoreEvent from './schema/LiveStoreEvent/mod.ts'
8
+ import type { LiveStoreSchema } from './schema/schema.ts'
9
9
  import type { QueryBuilder } from './schema/state/sqlite/query-builder/api.ts'
10
10
  import { isQueryBuilder } from './schema/state/sqlite/query-builder/api.ts'
11
11
  import { getResultSchema } from './schema/state/sqlite/query-builder/impl.ts'
@@ -24,8 +24,8 @@ export const getExecStatementsFromMaterializer = ({
24
24
  dbState: SqliteDb
25
25
  /** Both encoded and decoded events are supported to reduce the number of times we need to decode/encode */
26
26
  event:
27
- | { decoded: LiveStoreEvent.AnyDecoded; encoded: undefined }
28
- | { decoded: undefined; encoded: LiveStoreEvent.AnyEncoded }
27
+ | { decoded: LiveStoreEvent.Client.Decoded; encoded: undefined }
28
+ | { decoded: undefined; encoded: LiveStoreEvent.Client.Encoded }
29
29
  }): ReadonlyArray<{
30
30
  statementSql: string
31
31
  bindValues: PreparedBindValues
@@ -34,14 +34,14 @@ export const getExecStatementsFromMaterializer = ({
34
34
  const eventDecoded =
35
35
  event.decoded === undefined
36
36
  ? {
37
- ...event.encoded!,
38
- args: Schema.decodeUnknownSync(eventDef.schema)(event.encoded!.args),
37
+ ...event.encoded,
38
+ args: Schema.decodeUnknownSync(eventDef.schema)(event.encoded.args),
39
39
  }
40
40
  : event.decoded
41
41
 
42
- const eventArgsEncoded = isNil(event.decoded?.args)
42
+ const eventArgsEncoded = isNil(event.decoded?.args) === true
43
43
  ? undefined
44
- : Schema.encodeUnknownSync(eventDef.schema)(event.decoded!.args)
44
+ : Schema.encodeUnknownSync(eventDef.schema)(event.decoded.args)
45
45
 
46
46
  const query: MaterializerContextQuery = (
47
47
  rawQueryOrQueryBuilder:
@@ -51,7 +51,7 @@ export const getExecStatementsFromMaterializer = ({
51
51
  }
52
52
  | QueryBuilder.Any,
53
53
  ) => {
54
- if (isQueryBuilder(rawQueryOrQueryBuilder)) {
54
+ if (isQueryBuilder(rawQueryOrQueryBuilder) === true) {
55
55
  const { query, bindValues } = rawQueryOrQueryBuilder.asSql()
56
56
  const rawResults = dbState.select(query, prepareBindValues(bindValues, query))
57
57
  const resultSchema = getResultSchema(rawQueryOrQueryBuilder)
@@ -85,9 +85,20 @@ export const getExecStatementsFromMaterializer = ({
85
85
 
86
86
  export const makeMaterializerHash =
87
87
  ({ schema, dbState }: { schema: LiveStoreSchema; dbState: SqliteDb }) =>
88
- (event: LiveStoreEvent.AnyEncoded): Option.Option<number> => {
89
- if (isDevEnv()) {
90
- const { eventDef, materializer } = getEventDef(schema, event.name)
88
+ (event: LiveStoreEvent.Client.Encoded): Option.Option<number> => {
89
+ if (isDevEnv() === true) {
90
+ // Hashing is only needed during dev-mode diagnostics. Skip work entirely for
91
+ // unknown events (no definition/materializer) so we do not introduce noisy
92
+ // warnings while still returning `Option.none()` to disable hash checks.
93
+ const eventDef = schema.eventsDefsMap.get(event.name)
94
+ const materializer = schema.state.materializers.get(event.name)
95
+ if (eventDef === undefined || materializer === undefined) {
96
+ return Option.none()
97
+ }
98
+ // For known events we replay the materializer with the encoded payload and
99
+ // hash the resulting SQL statements. This lets us cheaply detect
100
+ // side-effects or logic drift between leader/client materializers without
101
+ // mutating the underlying state.
91
102
  const materializerResults = getExecStatementsFromMaterializer({
92
103
  eventDef,
93
104
  materializer,
@@ -115,10 +126,10 @@ const fromMaterializerResult = (
115
126
  bindValues: BindValues
116
127
  writeTables: ReadonlySet<string> | undefined
117
128
  }> => {
118
- if (isReadonlyArray(materializerResult)) {
129
+ if (isReadonlyArray(materializerResult) === true) {
119
130
  return materializerResult.flatMap(fromMaterializerResult)
120
131
  }
121
- if (isQueryBuilder(materializerResult)) {
132
+ if (isQueryBuilder(materializerResult) === true) {
122
133
  const { query, bindValues, usedTables } = materializerResult.asSql()
123
134
  return [{ sql: query, bindValues: bindValues as BindValues, writeTables: usedTables }]
124
135
  } else if (typeof materializerResult === 'string') {
@@ -144,7 +155,7 @@ export const replaceSessionIdSymbol = (
144
155
  }
145
156
 
146
157
  const deepReplaceValue = <S, R>(input: any, searchValue: S, replaceValue: R): void => {
147
- if (Array.isArray(input)) {
158
+ if (Array.isArray(input) === true) {
148
159
  for (const i in input) {
149
160
  if (input[i] === searchValue) {
150
161
  input[i] = replaceValue
package/src/otel.ts CHANGED
@@ -1,6 +1,17 @@
1
+ import * as otel from '@opentelemetry/api'
2
+
1
3
  import { makeNoopTracer } from '@livestore/utils'
2
4
  import { Effect, identity, Layer, OtelTracer } from '@livestore/utils/effect'
3
- import * as otel from '@opentelemetry/api'
5
+
6
+ export const OtelLiveDummy: Layer.Layer<OtelTracer.OtelTracer> = Layer.suspend(() => {
7
+ const OtelTracerLive = Layer.succeed(OtelTracer.OtelTracer, makeNoopTracer())
8
+
9
+ const TracingLive = Layer.unwrapEffect(Effect.map(OtelTracer.make, Layer.setTracer)).pipe(
10
+ Layer.provideMerge(OtelTracerLive),
11
+ )
12
+
13
+ return TracingLive
14
+ })
4
15
 
5
16
  export const provideOtel =
6
17
  ({ otelTracer, parentSpanContext }: { otelTracer?: otel.Tracer; parentSpanContext?: otel.Context }) =>
@@ -12,7 +23,7 @@ export const provideOtel =
12
23
  ) as any as Layer.Layer<OtelTracer.OtelTracer>
13
24
 
14
25
  return effect.pipe(
15
- parentSpanContext
26
+ parentSpanContext !== undefined
16
27
  ? Effect.withParentSpan(OtelTracer.makeExternalSpan(otel.trace.getSpanContext(parentSpanContext)!))
17
28
  : identity,
18
29
  Effect.provide(TracingLive),