@livestore/common 0.4.0-dev.9 → 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 (513) 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 +3 -3
  369. package/dist/testing/event-factory.d.ts.map +1 -1
  370. package/dist/testing/event-factory.js +5 -7
  371. package/dist/testing/event-factory.js.map +1 -1
  372. package/dist/util.js +2 -2
  373. package/dist/util.js.map +1 -1
  374. package/dist/version.d.ts +24 -5
  375. package/dist/version.d.ts.map +1 -1
  376. package/dist/version.js +25 -8
  377. package/dist/version.js.map +1 -1
  378. package/package.json +67 -15
  379. package/src/ClientSessionLeaderThreadProxy.ts +27 -12
  380. package/src/WorkerTransportError.ts +12 -0
  381. package/src/adapter-types.ts +50 -7
  382. package/src/bounded-collections.ts +6 -5
  383. package/src/debug-info.ts +37 -6
  384. package/src/devtools/devtools-compatibility.test.ts +18 -0
  385. package/src/devtools/devtools-messages-client-session.ts +22 -4
  386. package/src/devtools/devtools-messages-common.ts +7 -12
  387. package/src/devtools/devtools-messages-leader.ts +29 -10
  388. package/src/devtools/devtools-sessioninfo.ts +8 -5
  389. package/src/devtools/mod.ts +11 -2
  390. package/src/errors.ts +32 -24
  391. package/src/index.ts +4 -1
  392. package/src/leader-thread/LeaderSyncProcessor.ts +523 -373
  393. package/src/leader-thread/RejectedPushError.ts +106 -0
  394. package/src/leader-thread/connection.ts +1 -1
  395. package/src/leader-thread/eventlog.ts +112 -39
  396. package/src/leader-thread/leader-worker-devtools.ts +201 -120
  397. package/src/leader-thread/make-leader-thread-layer.test.ts +44 -0
  398. package/src/leader-thread/make-leader-thread-layer.ts +125 -40
  399. package/src/leader-thread/materialize-event.ts +40 -10
  400. package/src/leader-thread/mod.ts +1 -0
  401. package/src/leader-thread/recreate-db.ts +7 -7
  402. package/src/leader-thread/shutdown-channel.ts +4 -8
  403. package/src/leader-thread/stream-events.ts +206 -0
  404. package/src/leader-thread/types.ts +68 -18
  405. package/src/logging.ts +62 -0
  406. package/src/make-client-session.ts +11 -5
  407. package/src/materializer-helper.ts +27 -16
  408. package/src/otel.ts +13 -2
  409. package/src/rematerialize-from-eventlog.ts +61 -51
  410. package/src/schema/EventDef/define.ts +217 -0
  411. package/src/schema/EventDef/deprecated.test.ts +129 -0
  412. package/src/schema/EventDef/deprecated.ts +175 -0
  413. package/src/schema/EventDef/event-def.ts +125 -0
  414. package/src/schema/EventDef/facts.ts +135 -0
  415. package/src/schema/EventDef/materializer.ts +172 -0
  416. package/src/schema/EventDef/mod.ts +5 -0
  417. package/src/schema/EventSequenceNumber/client.ts +257 -0
  418. package/src/schema/EventSequenceNumber/global.ts +19 -0
  419. package/src/schema/EventSequenceNumber/mod.ts +37 -0
  420. package/src/schema/EventSequenceNumber.test.ts +72 -53
  421. package/src/schema/LiveStoreEvent/client.test.ts +129 -0
  422. package/src/schema/LiveStoreEvent/client.ts +235 -0
  423. package/src/schema/LiveStoreEvent/for-event-def.ts +60 -0
  424. package/src/schema/LiveStoreEvent/global.ts +45 -0
  425. package/src/schema/LiveStoreEvent/input.ts +63 -0
  426. package/src/schema/LiveStoreEvent/mod.ts +4 -0
  427. package/src/schema/events.ts +1 -1
  428. package/src/schema/mod.ts +6 -4
  429. package/src/schema/schema.ts +46 -5
  430. package/src/schema/state/sqlite/client-document-def.test.ts +144 -5
  431. package/src/schema/state/sqlite/client-document-def.ts +47 -34
  432. package/src/schema/state/sqlite/column-annotations.test.ts +3 -2
  433. package/src/schema/state/sqlite/column-annotations.ts +2 -1
  434. package/src/schema/state/sqlite/column-def.test.ts +66 -12
  435. package/src/schema/state/sqlite/column-def.ts +119 -47
  436. package/src/schema/state/sqlite/column-spec.test.ts +32 -17
  437. package/src/schema/state/sqlite/column-spec.ts +37 -11
  438. package/src/schema/state/sqlite/db-schema/ast/sqlite.ts +2 -2
  439. package/src/schema/state/sqlite/db-schema/dsl/field-defs.test.ts +2 -1
  440. package/src/schema/state/sqlite/db-schema/dsl/field-defs.ts +41 -15
  441. package/src/schema/state/sqlite/db-schema/dsl/mod.ts +13 -19
  442. package/src/schema/state/sqlite/mod.ts +7 -8
  443. package/src/schema/state/sqlite/query-builder/api.ts +55 -17
  444. package/src/schema/state/sqlite/query-builder/astToSql.ts +110 -21
  445. package/src/schema/state/sqlite/query-builder/impl.test.ts +267 -93
  446. package/src/schema/state/sqlite/query-builder/impl.ts +26 -13
  447. package/src/schema/state/sqlite/schema-helpers.test.ts +44 -0
  448. package/src/schema/state/sqlite/schema-helpers.ts +30 -22
  449. package/src/schema/state/sqlite/system-tables/eventlog-tables.ts +64 -0
  450. package/src/schema/state/sqlite/system-tables/mod.ts +2 -0
  451. package/src/schema/state/sqlite/system-tables/state-tables.ts +69 -0
  452. package/src/schema/state/sqlite/table-def.test.ts +114 -3
  453. package/src/schema/state/sqlite/table-def.ts +16 -22
  454. package/src/schema/unknown-events.ts +131 -0
  455. package/src/schema-management/__tests__/migrations-autoincrement-quoting.test.ts +88 -0
  456. package/src/schema-management/common.ts +2 -2
  457. package/src/schema-management/migrations.ts +42 -9
  458. package/src/schema-management/validate-schema.ts +3 -3
  459. package/src/sql-queries/sql-queries.ts +18 -6
  460. package/src/sql-queries/sql-query-builder.ts +1 -0
  461. package/src/sqlite-db-helper.ts +3 -3
  462. package/src/sqlite-types.ts +6 -5
  463. package/src/sync/ClientSessionSyncProcessor.ts +152 -142
  464. package/src/sync/errors.ts +12 -24
  465. package/src/sync/index.ts +2 -0
  466. package/src/sync/mock-sync-backend.ts +146 -104
  467. package/src/sync/next/compact-events.ts +10 -11
  468. package/src/sync/next/facts.ts +13 -14
  469. package/src/sync/next/history-dag-common.ts +280 -26
  470. package/src/sync/next/history-dag.ts +17 -13
  471. package/src/sync/next/rebase-events.ts +12 -12
  472. package/src/sync/next/test/compact-events.calculator.test.ts +3 -2
  473. package/src/sync/next/test/compact-events.test.ts +4 -3
  474. package/src/sync/next/test/event-fixtures.ts +13 -13
  475. package/src/sync/sync-backend-kv.ts +4 -3
  476. package/src/sync/sync-backend.ts +66 -17
  477. package/src/sync/sync.ts +24 -2
  478. package/src/sync/syncstate.test.ts +583 -419
  479. package/src/sync/syncstate.ts +127 -122
  480. package/src/sync/transport-chunking.ts +90 -0
  481. package/src/sync/validate-push-payload.ts +6 -8
  482. package/src/testing/event-factory.ts +10 -12
  483. package/src/util.ts +2 -2
  484. package/src/version.ts +33 -8
  485. package/dist/schema/EventDef.d.ts +0 -126
  486. package/dist/schema/EventDef.d.ts.map +0 -1
  487. package/dist/schema/EventDef.js +0 -46
  488. package/dist/schema/EventDef.js.map +0 -1
  489. package/dist/schema/EventSequenceNumber.d.ts +0 -80
  490. package/dist/schema/EventSequenceNumber.d.ts.map +0 -1
  491. package/dist/schema/EventSequenceNumber.js +0 -139
  492. package/dist/schema/EventSequenceNumber.js.map +0 -1
  493. package/dist/schema/LiveStoreEvent.d.ts.map +0 -1
  494. package/dist/schema/LiveStoreEvent.js +0 -147
  495. package/dist/schema/LiveStoreEvent.js.map +0 -1
  496. package/dist/schema/state/sqlite/system-tables.d.ts.map +0 -1
  497. package/dist/schema/state/sqlite/system-tables.js +0 -81
  498. package/dist/schema/state/sqlite/system-tables.js.map +0 -1
  499. package/dist/sync/next/graphology.d.ts +0 -8
  500. package/dist/sync/next/graphology.d.ts.map +0 -1
  501. package/dist/sync/next/graphology.js +0 -30
  502. package/dist/sync/next/graphology.js.map +0 -1
  503. package/dist/sync/next/graphology_.d.ts +0 -3
  504. package/dist/sync/next/graphology_.d.ts.map +0 -1
  505. package/dist/sync/next/graphology_.js +0 -3
  506. package/dist/sync/next/graphology_.js.map +0 -1
  507. package/src/schema/EventDef.ts +0 -222
  508. package/src/schema/EventSequenceNumber.ts +0 -199
  509. package/src/schema/LiveStoreEvent.ts +0 -286
  510. package/src/schema/state/sqlite/system-tables.ts +0 -106
  511. package/src/sync/next/ambient.d.ts +0 -3
  512. package/src/sync/next/graphology.ts +0 -41
  513. package/src/sync/next/graphology_.ts +0 -2
@@ -1,8 +1,8 @@
1
- import { casesHandled, LS_DEV, shouldNeverHappen } from '@livestore/utils'
2
- import { Match, ReadonlyArray, Schema } from '@livestore/utils/effect'
1
+ import { casesHandled } from '@livestore/utils'
2
+ import { Effect, Match, ReadonlyArray, Schema } from '@livestore/utils/effect'
3
3
 
4
- import * as EventSequenceNumber from '../schema/EventSequenceNumber.ts'
5
- import * as LiveStoreEvent from '../schema/LiveStoreEvent.ts'
4
+ import * as EventSequenceNumber from '../schema/EventSequenceNumber/mod.ts'
5
+ import * as LiveStoreEvent from '../schema/LiveStoreEvent/mod.ts'
6
6
 
7
7
  /**
8
8
  * SyncState represents the current sync state of a sync node relative to an upstream node.
@@ -15,7 +15,7 @@ import * as LiveStoreEvent from '../schema/LiveStoreEvent.ts'
15
15
  * +------------------------+
16
16
  * ▼ ▼
17
17
  * Upstream Head Local Head
18
- * (1,0) (1,1), (1,2), (2,0)
18
+ * e1 e1.1, e1.2, e2
19
19
  * ```
20
20
  *
21
21
  * **Pending Events**: Events awaiting acknowledgment from the upstream.
@@ -31,7 +31,7 @@ import * as LiveStoreEvent from '../schema/LiveStoreEvent.ts'
31
31
  * Invariants:
32
32
  * 1. **Chain Continuity**: Each event must reference its immediate parent.
33
33
  * 2. **Head Ordering**: Upstream Head ≤ Local Head.
34
- * 3. **Event number sequence**: Must follow the pattern (1,0)(1,1)(1,2)(2,0).
34
+ * 3. **Event number sequence**: Must follow the pattern e1e1.1→e1.2→e2.
35
35
  *
36
36
  * A few further notes to help form an intuition:
37
37
  * - The goal is to keep the pending events as small as possible (i.e. to have synced with the next upstream node)
@@ -42,16 +42,16 @@ import * as LiveStoreEvent from '../schema/LiveStoreEvent.ts'
42
42
  * handling cases such as upstream rebase, advance and local push.
43
43
  */
44
44
  export class SyncState extends Schema.Class<SyncState>('SyncState')({
45
- pending: Schema.Array(LiveStoreEvent.EncodedWithMeta),
45
+ pending: Schema.Array(LiveStoreEvent.Client.EncodedWithMeta),
46
46
  /** What this node expects the next upstream node to have as its own local head */
47
- upstreamHead: EventSequenceNumber.EventSequenceNumber,
47
+ upstreamHead: EventSequenceNumber.Client.Composite,
48
48
  /** Equivalent to `pending.at(-1)?.id` if there are pending events */
49
- localHead: EventSequenceNumber.EventSequenceNumber,
49
+ localHead: EventSequenceNumber.Client.Composite,
50
50
  }) {
51
51
  toJSON = (): any => ({
52
52
  pending: this.pending.map((e) => e.toJSON()),
53
- upstreamHead: EventSequenceNumber.toString(this.upstreamHead),
54
- localHead: EventSequenceNumber.toString(this.localHead),
53
+ upstreamHead: EventSequenceNumber.Client.toString(this.upstreamHead),
54
+ localHead: EventSequenceNumber.Client.toString(this.localHead),
55
55
  })
56
56
  }
57
57
 
@@ -60,17 +60,17 @@ export class SyncState extends Schema.Class<SyncState>('SyncState')({
60
60
  */
61
61
  export class PayloadUpstreamRebase extends Schema.TaggedStruct('upstream-rebase', {
62
62
  /** Events which need to be rolled back */
63
- rollbackEvents: Schema.Array(LiveStoreEvent.EncodedWithMeta),
63
+ rollbackEvents: Schema.Array(LiveStoreEvent.Client.EncodedWithMeta),
64
64
  /** Events which need to be applied after the rollback (already rebased by the upstream node) */
65
- newEvents: Schema.Array(LiveStoreEvent.EncodedWithMeta),
65
+ newEvents: Schema.Array(LiveStoreEvent.Client.EncodedWithMeta),
66
66
  }) {}
67
67
 
68
68
  export class PayloadUpstreamAdvance extends Schema.TaggedStruct('upstream-advance', {
69
- newEvents: Schema.Array(LiveStoreEvent.EncodedWithMeta),
69
+ newEvents: Schema.Array(LiveStoreEvent.Client.EncodedWithMeta),
70
70
  }) {}
71
71
 
72
72
  export class PayloadLocalPush extends Schema.TaggedStruct('local-push', {
73
- newEvents: Schema.Array(LiveStoreEvent.EncodedWithMeta),
73
+ newEvents: Schema.Array(LiveStoreEvent.Client.EncodedWithMeta),
74
74
  }) {}
75
75
 
76
76
  export class Payload extends Schema.Union(PayloadUpstreamRebase, PayloadUpstreamAdvance, PayloadLocalPush) {}
@@ -109,9 +109,9 @@ export class MergeContext extends Schema.Class<MergeContext>('MergeContext')({
109
109
  export class MergeResultAdvance extends Schema.Class<MergeResultAdvance>('MergeResultAdvance')({
110
110
  _tag: Schema.Literal('advance'),
111
111
  newSyncState: SyncState,
112
- newEvents: Schema.Array(LiveStoreEvent.EncodedWithMeta),
112
+ newEvents: Schema.Array(LiveStoreEvent.Client.EncodedWithMeta),
113
113
  /** Events which were previously pending but are now confirmed */
114
- confirmedEvents: Schema.Array(LiveStoreEvent.EncodedWithMeta),
114
+ confirmedEvents: Schema.Array(LiveStoreEvent.Client.EncodedWithMeta),
115
115
  mergeContext: MergeContext,
116
116
  }) {
117
117
  toJSON = (): any => {
@@ -128,9 +128,9 @@ export class MergeResultAdvance extends Schema.Class<MergeResultAdvance>('MergeR
128
128
  export class MergeResultRebase extends Schema.Class<MergeResultRebase>('MergeResultRebase')({
129
129
  _tag: Schema.Literal('rebase'),
130
130
  newSyncState: SyncState,
131
- newEvents: Schema.Array(LiveStoreEvent.EncodedWithMeta),
131
+ newEvents: Schema.Array(LiveStoreEvent.Client.EncodedWithMeta),
132
132
  /** Events which need to be rolled back */
133
- rollbackEvents: Schema.Array(LiveStoreEvent.EncodedWithMeta),
133
+ rollbackEvents: Schema.Array(LiveStoreEvent.Client.EncodedWithMeta),
134
134
  mergeContext: MergeContext,
135
135
  }) {
136
136
  toJSON = (): any => {
@@ -147,28 +147,22 @@ export class MergeResultRebase extends Schema.Class<MergeResultRebase>('MergeRes
147
147
  export class MergeResultReject extends Schema.Class<MergeResultReject>('MergeResultReject')({
148
148
  _tag: Schema.Literal('reject'),
149
149
  /** The minimum id that the new events must have */
150
- expectedMinimumId: EventSequenceNumber.EventSequenceNumber,
150
+ expectedMinimumId: EventSequenceNumber.Client.Composite,
151
151
  mergeContext: MergeContext,
152
152
  }) {
153
153
  toJSON = (): any => {
154
154
  return {
155
155
  _tag: this._tag,
156
- expectedMinimumId: EventSequenceNumber.toString(this.expectedMinimumId),
156
+ expectedMinimumId: EventSequenceNumber.Client.toString(this.expectedMinimumId),
157
157
  mergeContext: this.mergeContext.toJSON(),
158
158
  }
159
159
  }
160
160
  }
161
161
 
162
- export class MergeResultUnexpectedError extends Schema.Class<MergeResultUnexpectedError>('MergeResultUnexpectedError')({
163
- _tag: Schema.Literal('unexpected-error'),
164
- message: Schema.String,
165
- }) {}
166
-
167
162
  export class MergeResult extends Schema.Union(
168
163
  MergeResultAdvance,
169
164
  MergeResultRebase,
170
165
  MergeResultReject,
171
- MergeResultUnexpectedError,
172
166
  ) {}
173
167
 
174
168
  export const payloadFromMergeResult = (
@@ -187,15 +181,6 @@ export const payloadFromMergeResult = (
187
181
  Match.exhaustive,
188
182
  )
189
183
 
190
- const unexpectedError = (message: string): MergeResultUnexpectedError => {
191
- if (LS_DEV) {
192
- // biome-ignore lint/suspicious/noDebugger: debug
193
- debugger
194
- }
195
-
196
- return MergeResultUnexpectedError.make({ _tag: 'unexpected-error', message })
197
- }
198
-
199
184
  // TODO Idea: call merge recursively through hierarchy levels
200
185
  /*
201
186
  Idea: have a map that maps from `globalEventSequenceNumber` to Array<ClientEvents>
@@ -203,7 +188,7 @@ The same applies to even further hierarchy levels
203
188
 
204
189
  TODO: possibly even keep the client events in a separate table in the client leader
205
190
  */
206
- export const merge = ({
191
+ export const merge = Effect.fnUntraced(function* ({
207
192
  syncState,
208
193
  payload,
209
194
  isClientEvent,
@@ -212,13 +197,13 @@ export const merge = ({
212
197
  }: {
213
198
  syncState: SyncState
214
199
  payload: typeof Payload.Type
215
- isClientEvent: (event: LiveStoreEvent.EncodedWithMeta) => boolean
216
- isEqualEvent: (a: LiveStoreEvent.EncodedWithMeta, b: LiveStoreEvent.EncodedWithMeta) => boolean
200
+ isClientEvent: (event: LiveStoreEvent.Client.EncodedWithMeta) => boolean
201
+ isEqualEvent: (a: LiveStoreEvent.Client.EncodedWithMeta, b: LiveStoreEvent.Client.EncodedWithMeta) => boolean
217
202
  /** This is used in the leader which should ignore client events when receiving an upstream-advance payload */
218
203
  ignoreClientEvents?: boolean
219
- }): typeof MergeResult.Type => {
220
- validateSyncState(syncState)
221
- validatePayload(payload)
204
+ }) {
205
+ yield* validateSyncState(syncState)
206
+ yield* validatePayload(payload)
222
207
 
223
208
  const mergeContext = MergeContext.make({ payload, syncState })
224
209
 
@@ -236,7 +221,7 @@ export const merge = ({
236
221
  isClientEvent,
237
222
  })
238
223
 
239
- return validateMergeResult(
224
+ return yield* validateMergeResult(
240
225
  MergeResultRebase.make({
241
226
  _tag: 'rebase',
242
227
  newSyncState: new SyncState({
@@ -251,10 +236,10 @@ export const merge = ({
251
236
  )
252
237
  }
253
238
 
254
- // #region upstream-advance
239
+ //#region upstream-advance
255
240
  case 'upstream-advance': {
256
241
  if (payload.newEvents.length === 0) {
257
- return validateMergeResult(
242
+ return yield* validateMergeResult(
258
243
  MergeResultAdvance.make({
259
244
  _tag: 'advance',
260
245
  newSyncState: new SyncState({
@@ -271,20 +256,23 @@ export const merge = ({
271
256
 
272
257
  // Validate that newEvents are sorted in ascending order by eventNum
273
258
  for (let i = 1; i < payload.newEvents.length; i++) {
274
- if (EventSequenceNumber.isGreaterThan(payload.newEvents[i - 1]!.seqNum, payload.newEvents[i]!.seqNum)) {
275
- return unexpectedError(
276
- `Events must be sorted in ascending order by event number. Received: [${payload.newEvents.map((e) => EventSequenceNumber.toString(e.seqNum)).join(', ')}]`,
259
+ if (
260
+ EventSequenceNumber.Client.isGreaterThan(payload.newEvents[i - 1]!.seqNum, payload.newEvents[i]!.seqNum) ===
261
+ true
262
+ ) {
263
+ return yield* Effect.dieDebugger(
264
+ `Events must be sorted in ascending order by event number. Received: [${payload.newEvents.map((e) => EventSequenceNumber.Client.toString(e.seqNum)).join(', ')}]`,
277
265
  )
278
266
  }
279
267
  }
280
268
 
281
269
  // Validate that incoming events are larger than upstream head
282
270
  if (
283
- EventSequenceNumber.isGreaterThan(syncState.upstreamHead, payload.newEvents[0]!.seqNum) ||
284
- EventSequenceNumber.isEqual(syncState.upstreamHead, payload.newEvents[0]!.seqNum)
271
+ EventSequenceNumber.Client.isGreaterThan(syncState.upstreamHead, payload.newEvents[0]!.seqNum) === true ||
272
+ EventSequenceNumber.Client.isEqual(syncState.upstreamHead, payload.newEvents[0]!.seqNum) === true
285
273
  ) {
286
- return unexpectedError(
287
- `Incoming events must be greater than upstream head. Expected greater than: ${EventSequenceNumber.toString(syncState.upstreamHead)}. Received: [${payload.newEvents.map((e) => EventSequenceNumber.toString(e.seqNum)).join(', ')}]`,
274
+ return yield* Effect.dieDebugger(
275
+ `Incoming events must be greater than upstream head. Expected greater than: ${EventSequenceNumber.Client.toString(syncState.upstreamHead)}. Received: [${payload.newEvents.map((e) => EventSequenceNumber.Client.toString(e.seqNum)).join(', ')}]`,
288
276
  )
289
277
  }
290
278
 
@@ -316,27 +304,27 @@ export const merge = ({
316
304
  const [pendingMatching, pendingRemaining] = ReadonlyArray.splitWhere(
317
305
  syncState.pending,
318
306
  (pendingEvent, index) => {
319
- if (ignoreClientEvents && isClientEvent(pendingEvent)) {
307
+ if (ignoreClientEvents === true && isClientEvent(pendingEvent) === true) {
320
308
  clientIndexOffset++
321
309
  return false
322
310
  }
323
311
 
324
312
  const newEvent = payload.newEvents.at(index - clientIndexOffset)
325
- if (!newEvent) {
313
+ if (newEvent == null) {
326
314
  return true
327
315
  }
328
- return isEqualEvent(pendingEvent, newEvent) === false
316
+ return !isEqualEvent(pendingEvent, newEvent)
329
317
  },
330
318
  )
331
319
 
332
- return validateMergeResult(
320
+ return yield* validateMergeResult(
333
321
  MergeResultAdvance.make({
334
322
  _tag: 'advance',
335
323
  newSyncState: new SyncState({
336
324
  pending: pendingRemaining,
337
325
  upstreamHead: newUpstreamHead,
338
326
  localHead:
339
- pendingRemaining.at(-1)?.seqNum ?? EventSequenceNumber.max(syncState.localHead, newUpstreamHead),
327
+ pendingRemaining.at(-1)?.seqNum ?? EventSequenceNumber.Client.max(syncState.localHead, newUpstreamHead),
340
328
  }),
341
329
  newEvents,
342
330
  confirmedEvents: pendingMatching,
@@ -359,7 +347,7 @@ export const merge = ({
359
347
  ignoreClientEvents,
360
348
  })
361
349
 
362
- return validateMergeResult(
350
+ return yield* validateMergeResult(
363
351
  MergeResultRebase.make({
364
352
  _tag: 'rebase',
365
353
  newSyncState: new SyncState({
@@ -374,12 +362,12 @@ export const merge = ({
374
362
  )
375
363
  }
376
364
  }
377
- // #endregion
365
+ //#endregion upstream-advance
378
366
 
379
367
  // This is the same as what's running in the sync backend
380
368
  case 'local-push': {
381
369
  if (payload.newEvents.length === 0) {
382
- return validateMergeResult(
370
+ return yield* validateMergeResult(
383
371
  MergeResultAdvance.make({
384
372
  _tag: 'advance',
385
373
  newSyncState: syncState,
@@ -391,15 +379,17 @@ export const merge = ({
391
379
  }
392
380
 
393
381
  const newEventsFirst = payload.newEvents.at(0)!
394
- const invalidEventSequenceNumber =
395
- EventSequenceNumber.isGreaterThan(newEventsFirst.seqNum, syncState.localHead) === false
382
+ const invalidEventSequenceNumber = !EventSequenceNumber.Client.isGreaterThan(
383
+ newEventsFirst.seqNum,
384
+ syncState.localHead,
385
+ )
396
386
 
397
- if (invalidEventSequenceNumber) {
398
- const expectedMinimumId = EventSequenceNumber.nextPair({
387
+ if (invalidEventSequenceNumber === true) {
388
+ const expectedMinimumId = EventSequenceNumber.Client.nextPair({
399
389
  seqNum: syncState.localHead,
400
390
  isClient: true,
401
391
  }).seqNum
402
- return validateMergeResult(
392
+ return yield* validateMergeResult(
403
393
  MergeResultReject.make({
404
394
  _tag: 'reject',
405
395
  expectedMinimumId,
@@ -407,13 +397,19 @@ export const merge = ({
407
397
  }),
408
398
  )
409
399
  } else {
410
- return validateMergeResult(
400
+ const nonClientEvents =
401
+ ignoreClientEvents === true ? payload.newEvents.filter((event) => !isClientEvent(event)) : payload.newEvents
402
+ const newPending = [...syncState.pending, ...nonClientEvents]
403
+ const newLocalHead =
404
+ newPending.at(-1)?.seqNum ?? EventSequenceNumber.Client.max(syncState.localHead, syncState.upstreamHead)
405
+
406
+ return yield* validateMergeResult(
411
407
  MergeResultAdvance.make({
412
408
  _tag: 'advance',
413
409
  newSyncState: new SyncState({
414
- pending: [...syncState.pending, ...payload.newEvents],
410
+ pending: newPending,
415
411
  upstreamHead: syncState.upstreamHead,
416
- localHead: payload.newEvents.at(-1)!.seqNum,
412
+ localHead: newLocalHead,
417
413
  }),
418
414
  newEvents: payload.newEvents,
419
415
  confirmedEvents: [],
@@ -423,11 +419,10 @@ export const merge = ({
423
419
  }
424
420
  }
425
421
 
426
- default: {
427
- casesHandled(payload)
428
- }
422
+ default:
423
+ return casesHandled(payload)
429
424
  }
430
- }
425
+ })
431
426
 
432
427
  /**
433
428
  * Gets the index relative to `existingEvents` where the divergence point is
@@ -440,13 +435,13 @@ export const findDivergencePoint = ({
440
435
  isClientEvent,
441
436
  ignoreClientEvents,
442
437
  }: {
443
- existingEvents: ReadonlyArray<LiveStoreEvent.EncodedWithMeta>
444
- incomingEvents: ReadonlyArray<LiveStoreEvent.EncodedWithMeta>
445
- isEqualEvent: (a: LiveStoreEvent.EncodedWithMeta, b: LiveStoreEvent.EncodedWithMeta) => boolean
446
- isClientEvent: (event: LiveStoreEvent.EncodedWithMeta) => boolean
438
+ existingEvents: ReadonlyArray<LiveStoreEvent.Client.EncodedWithMeta>
439
+ incomingEvents: ReadonlyArray<LiveStoreEvent.Client.EncodedWithMeta>
440
+ isEqualEvent: (a: LiveStoreEvent.Client.EncodedWithMeta, b: LiveStoreEvent.Client.EncodedWithMeta) => boolean
441
+ isClientEvent: (event: LiveStoreEvent.Client.EncodedWithMeta) => boolean
447
442
  ignoreClientEvents: boolean
448
443
  }): number => {
449
- if (ignoreClientEvents) {
444
+ if (ignoreClientEvents === true) {
450
445
  const filteredExistingEvents = existingEvents.filter((event) => !isClientEvent(event))
451
446
  const divergencePointWithoutClientEvents = findDivergencePoint({
452
447
  existingEvents: filteredExistingEvents,
@@ -461,14 +456,14 @@ export const findDivergencePoint = ({
461
456
  const divergencePointEventSequenceNumber = existingEvents[divergencePointWithoutClientEvents]!.seqNum
462
457
  // Now find the divergence point in the original array
463
458
  return existingEvents.findIndex((event) =>
464
- EventSequenceNumber.isEqual(event.seqNum, divergencePointEventSequenceNumber),
459
+ EventSequenceNumber.Client.isEqual(event.seqNum, divergencePointEventSequenceNumber),
465
460
  )
466
461
  }
467
462
 
468
463
  return existingEvents.findIndex((existingEvent, index) => {
469
464
  const incomingEvent = incomingEvents[index]
470
465
  // return !incomingEvent || !isEqualEvent(existingEvent, incomingEvent)
471
- return incomingEvent && !isEqualEvent(existingEvent, incomingEvent)
466
+ return incomingEvent !== undefined && isEqualEvent(existingEvent, incomingEvent) === false
472
467
  })
473
468
  }
474
469
 
@@ -477,10 +472,10 @@ const rebaseEvents = ({
477
472
  baseEventSequenceNumber,
478
473
  isClientEvent,
479
474
  }: {
480
- events: ReadonlyArray<LiveStoreEvent.EncodedWithMeta>
481
- baseEventSequenceNumber: EventSequenceNumber.EventSequenceNumber
482
- isClientEvent: (event: LiveStoreEvent.EncodedWithMeta) => boolean
483
- }): ReadonlyArray<LiveStoreEvent.EncodedWithMeta> => {
475
+ events: ReadonlyArray<LiveStoreEvent.Client.EncodedWithMeta>
476
+ baseEventSequenceNumber: EventSequenceNumber.Client.Composite
477
+ isClientEvent: (event: LiveStoreEvent.Client.EncodedWithMeta) => boolean
478
+ }): ReadonlyArray<LiveStoreEvent.Client.EncodedWithMeta> => {
484
479
  let prevEventSequenceNumber = baseEventSequenceNumber
485
480
  const rebaseGeneration = baseEventSequenceNumber.rebaseGeneration + 1
486
481
  return events.map((event) => {
@@ -504,65 +499,75 @@ const rebaseEvents = ({
504
499
  */
505
500
  const _flattenMergeResults = (_updateResults: ReadonlyArray<MergeResult>) => {}
506
501
 
507
- const validatePayload = (payload: typeof Payload.Type) => {
508
- for (let i = 1; i < payload.newEvents.length; i++) {
509
- if (EventSequenceNumber.isGreaterThanOrEqual(payload.newEvents[i - 1]!.seqNum, payload.newEvents[i]!.seqNum)) {
510
- return unexpectedError(
511
- `Events must be ordered in monotonically ascending order by eventNum. Received: [${payload.newEvents.map((e) => EventSequenceNumber.toString(e.seqNum)).join(', ')}]`,
512
- )
502
+ const validatePayload = (payload: typeof Payload.Type) =>
503
+ Effect.gen(function* () {
504
+ for (let i = 1; i < payload.newEvents.length; i++) {
505
+ if (
506
+ EventSequenceNumber.Client.isGreaterThanOrEqual(
507
+ payload.newEvents[i - 1]!.seqNum,
508
+ payload.newEvents[i]!.seqNum,
509
+ ) === true
510
+ ) {
511
+ return yield* Effect.dieDebugger(
512
+ `Events must be ordered in monotonically ascending order by eventNum. Received: [${payload.newEvents.map((e) => EventSequenceNumber.Client.toString(e.seqNum)).join(', ')}]`,
513
+ )
514
+ }
513
515
  }
514
- }
515
- }
516
+ })
516
517
 
517
- const validateSyncState = (syncState: SyncState) => {
518
+ const validateSyncState = Effect.fnUntraced(function* (
519
+ syncState: SyncState,
520
+ ) {
518
521
  for (let i = 0; i < syncState.pending.length; i++) {
519
522
  const event = syncState.pending[i]!
520
523
  const nextEvent = syncState.pending[i + 1]
521
524
  if (nextEvent === undefined) break // Reached end of chain
522
525
 
523
- if (EventSequenceNumber.isGreaterThanOrEqual(event.seqNum, nextEvent.seqNum)) {
524
- shouldNeverHappen(
525
- `Events must be ordered in monotonically ascending order by eventNum. Received: [${syncState.pending.map((e) => EventSequenceNumber.toString(e.seqNum)).join(', ')}]`,
526
- {
527
- event,
528
- nextEvent,
529
- },
526
+ if (EventSequenceNumber.Client.isGreaterThanOrEqual(event.seqNum, nextEvent.seqNum) === true) {
527
+ return yield* Effect.dieDebugger(
528
+ `Events must be ordered in monotonically ascending order by eventNum. Received: [${syncState.pending.map((e) => EventSequenceNumber.Client.toString(e.seqNum)).join(', ')}]`,
529
+ { event, nextEvent },
530
530
  )
531
531
  }
532
532
 
533
533
  // If the global id has increased, then the client id must be 0
534
534
  const globalIdHasIncreased = nextEvent.seqNum.global > event.seqNum.global
535
- if (globalIdHasIncreased) {
535
+ if (globalIdHasIncreased === true) {
536
536
  if (nextEvent.seqNum.client !== 0) {
537
- shouldNeverHappen(
538
- `New global events must point to clientId 0 in the parentSeqNum. Received: (${EventSequenceNumber.toString(nextEvent.seqNum)})`,
537
+ return yield* Effect.dieDebugger(
538
+ `New global events must point to clientId 0 in the parentSeqNum. Received: (${EventSequenceNumber.Client.toString(nextEvent.seqNum)})`,
539
539
  syncState.pending,
540
- {
541
- event,
542
- nextEvent,
543
- },
540
+ { event, nextEvent },
544
541
  )
545
542
  }
546
543
  } else {
547
544
  // Otherwise, the parentSeqNum must be the same as the previous event's id
548
- if (EventSequenceNumber.isEqual(nextEvent.parentSeqNum, event.seqNum) === false) {
549
- shouldNeverHappen('Events must be linked in a continuous chain via the parentSeqNum', syncState.pending, {
550
- event,
551
- nextEvent,
552
- })
545
+ if (EventSequenceNumber.Client.isEqual(nextEvent.parentSeqNum, event.seqNum) === false) {
546
+ return yield* Effect.dieDebugger(
547
+ 'Events must be linked in a continuous chain via the parentSeqNum',
548
+ syncState.pending,
549
+ { event, nextEvent },
550
+ )
553
551
  }
554
552
  }
555
553
  }
556
- }
554
+ })
557
555
 
558
- const validateMergeResult = (mergeResult: typeof MergeResult.Type) => {
559
- if (mergeResult._tag === 'unexpected-error' || mergeResult._tag === 'reject') return mergeResult
556
+ const validateMergeResult = Effect.fnUntraced(function* (
557
+ mergeResult: typeof MergeResult.Type,
558
+ ) {
559
+ if (mergeResult._tag === 'reject') return mergeResult
560
560
 
561
- validateSyncState(mergeResult.newSyncState)
561
+ yield* validateSyncState(mergeResult.newSyncState)
562
562
 
563
563
  // Ensure local head is always greater than or equal to upstream head
564
- if (EventSequenceNumber.isGreaterThan(mergeResult.newSyncState.upstreamHead, mergeResult.newSyncState.localHead)) {
565
- shouldNeverHappen('Local head must be greater than or equal to upstream head', {
564
+ if (
565
+ EventSequenceNumber.Client.isGreaterThan(
566
+ mergeResult.newSyncState.upstreamHead,
567
+ mergeResult.newSyncState.localHead,
568
+ ) === true
569
+ ) {
570
+ return yield* Effect.dieDebugger('Local head must be greater than or equal to upstream head', {
566
571
  localHead: mergeResult.newSyncState.localHead,
567
572
  upstreamHead: mergeResult.newSyncState.upstreamHead,
568
573
  })
@@ -570,12 +575,12 @@ const validateMergeResult = (mergeResult: typeof MergeResult.Type) => {
570
575
 
571
576
  // Ensure new local head is greater than or equal to the previous local head
572
577
  if (
573
- EventSequenceNumber.isGreaterThanOrEqual(
578
+ EventSequenceNumber.Client.isGreaterThanOrEqual(
574
579
  mergeResult.newSyncState.localHead,
575
580
  mergeResult.mergeContext.syncState.localHead,
576
581
  ) === false
577
582
  ) {
578
- shouldNeverHappen('New local head must be greater than or equal to the previous local head', {
583
+ return yield* Effect.dieDebugger('New local head must be greater than or equal to the previous local head', {
579
584
  localHead: mergeResult.newSyncState.localHead,
580
585
  previousLocalHead: mergeResult.mergeContext.syncState.localHead,
581
586
  })
@@ -583,16 +588,16 @@ const validateMergeResult = (mergeResult: typeof MergeResult.Type) => {
583
588
 
584
589
  // Ensure new upstream head is greater than or equal to the previous upstream head
585
590
  if (
586
- EventSequenceNumber.isGreaterThanOrEqual(
591
+ EventSequenceNumber.Client.isGreaterThanOrEqual(
587
592
  mergeResult.newSyncState.upstreamHead,
588
593
  mergeResult.mergeContext.syncState.upstreamHead,
589
594
  ) === false
590
595
  ) {
591
- shouldNeverHappen('New upstream head must be greater than or equal to the previous upstream head', {
596
+ return yield* Effect.dieDebugger('New upstream head must be greater than or equal to the previous upstream head', {
592
597
  upstreamHead: mergeResult.newSyncState.upstreamHead,
593
598
  previousUpstreamHead: mergeResult.mergeContext.syncState.upstreamHead,
594
599
  })
595
600
  }
596
601
 
597
602
  return mergeResult
598
- }
603
+ })
@@ -0,0 +1,90 @@
1
+ import { Chunk, Effect, Schema } from '@livestore/utils/effect'
2
+
3
+ const textEncoder = new TextEncoder()
4
+
5
+ /**
6
+ * Configuration describing how to break a chunk into smaller payload-safe chunks.
7
+ */
8
+ export interface ChunkingOptions<A> {
9
+ /** Maximum number of items that may appear in any emitted chunk. */
10
+ readonly maxItems: number
11
+ /** Maximum encoded byte size allowed for any emitted chunk. */
12
+ readonly maxBytes: number
13
+ /**
14
+ * Callback that produces a JSON-serialisable structure whose byte size should
15
+ * fit within {@link maxBytes}. This lets callers control framing overhead.
16
+ */
17
+ readonly encode: (items: ReadonlyArray<A>) => unknown
18
+ /**
19
+ * Optional custom measurement function. When provided it overrides the
20
+ * default {@link JSON.stringify}-based measurement logic.
21
+ */
22
+ readonly measure?: (items: ReadonlyArray<A>) => number
23
+ }
24
+
25
+ /**
26
+ * Derives a function that splits an input chunk into sub-chunks confined by
27
+ * both item count and encoded byte size limits. Designed for transports with
28
+ * strict frame caps (e.g. Cloudflare hibernated WebSockets).
29
+ */
30
+ export class OversizeChunkItemError extends Schema.TaggedError<OversizeChunkItemError>('~@livestore/common/OversizeChunkItemError')('OversizeChunkItemError', {
31
+ size: Schema.Number,
32
+ maxBytes: Schema.Number,
33
+ }) {}
34
+
35
+ export const splitChunkBySize =
36
+ <A>(options: ChunkingOptions<A>) =>
37
+ (chunk: Chunk.Chunk<A>): Effect.Effect<Chunk.Chunk<Chunk.Chunk<A>>, OversizeChunkItemError> =>
38
+ Effect.gen(function* () {
39
+ const maxItems = Math.max(1, options.maxItems)
40
+ const maxBytes = Math.max(1, options.maxBytes)
41
+ const encode = options.encode
42
+ const measure = options.measure
43
+
44
+ const computeSize = (items: ReadonlyArray<A>) => {
45
+ if (measure !== undefined) {
46
+ return measure(items)
47
+ }
48
+
49
+ const encoded = encode(items)
50
+ return textEncoder.encode(JSON.stringify(encoded)).byteLength
51
+ }
52
+
53
+ const items = Chunk.toReadonlyArray(chunk)
54
+ if (items.length === 0) {
55
+ return Chunk.fromIterable<Chunk.Chunk<A>>([])
56
+ }
57
+
58
+ const result: Array<Chunk.Chunk<A>> = []
59
+ let current: Array<A> = []
60
+
61
+ const flushCurrent = () => {
62
+ if (current.length > 0) {
63
+ result.push(Chunk.fromIterable(current))
64
+ current = []
65
+ }
66
+ }
67
+
68
+ for (const item of items) {
69
+ current.push(item)
70
+ const exceedsLimit = current.length > maxItems || computeSize(current) > maxBytes
71
+
72
+ if (exceedsLimit === true) {
73
+ // remove the item we just added and emit the previous chunk if it exists
74
+ const last = current.pop()!
75
+ flushCurrent()
76
+
77
+ if (last !== undefined) {
78
+ current = [last]
79
+ const singleItemTooLarge = computeSize(current) > maxBytes
80
+ if (singleItemTooLarge === true || current.length > maxItems) {
81
+ return yield* new OversizeChunkItemError({ size: computeSize([last]), maxBytes })
82
+ }
83
+ }
84
+ }
85
+ }
86
+
87
+ flushCurrent()
88
+
89
+ return Chunk.fromIterable(result)
90
+ })
@@ -1,20 +1,18 @@
1
1
  import { Effect } from '@livestore/utils/effect'
2
2
 
3
3
  import { EventSequenceNumber, type LiveStoreEvent } from '../schema/mod.ts'
4
- import { InvalidPushError, ServerAheadError } from './sync.ts'
4
+ import { ServerAheadError } from './sync.ts'
5
5
 
6
6
  // TODO proper batch validation
7
7
  export const validatePushPayload = (
8
- batch: ReadonlyArray<LiveStoreEvent.AnyEncodedGlobal>,
9
- currentEventSequenceNumber: EventSequenceNumber.GlobalEventSequenceNumber,
8
+ batch: ReadonlyArray<LiveStoreEvent.Global.Encoded>,
9
+ currentEventSequenceNumber: EventSequenceNumber.Global.Type,
10
10
  ) =>
11
11
  Effect.gen(function* () {
12
12
  if (batch[0]!.seqNum <= currentEventSequenceNumber) {
13
- return yield* InvalidPushError.make({
14
- cause: new ServerAheadError({
15
- minimumExpectedNum: EventSequenceNumber.globalEventSequenceNumber(currentEventSequenceNumber + 1),
16
- providedNum: EventSequenceNumber.globalEventSequenceNumber(batch[0]!.seqNum),
17
- }),
13
+ return yield* new ServerAheadError({
14
+ minimumExpectedNum: EventSequenceNumber.Global.make(currentEventSequenceNumber + 1),
15
+ providedNum: EventSequenceNumber.Global.make(batch[0]!.seqNum),
18
16
  })
19
17
  }
20
18
  })