@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
@@ -0,0 +1,125 @@
1
+ import type { Schema } from '@livestore/utils/effect'
2
+
3
+ import type { FactsCallback } from './facts.ts'
4
+
5
+ /**
6
+ * Core type representing an event definition in LiveStore.
7
+ *
8
+ * An EventDef defines the structure and behavior of an event type, including:
9
+ * - A unique name identifying the event type (conventionally versioned, e.g., `v1.TodoCreated`)
10
+ * - A schema for validating and encoding/decoding event arguments
11
+ * - Options controlling sync behavior and constraints
12
+ *
13
+ * EventDefs are callable - invoking them creates a partial event object suitable for `store.commit()`.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { Events } from '@livestore/livestore'
18
+ * import { Schema } from 'effect'
19
+ *
20
+ * const todoCreated = Events.synced({
21
+ * name: 'v1.TodoCreated',
22
+ * schema: Schema.Struct({
23
+ * id: Schema.String,
24
+ * text: Schema.String,
25
+ * }),
26
+ * })
27
+ *
28
+ * // Use the EventDef as a constructor
29
+ * store.commit(todoCreated({ id: 'abc', text: 'Buy milk' }))
30
+ * ```
31
+ */
32
+ export type EventDef<TName extends string, TType, TEncoded = TType, TDerived extends boolean = false> = {
33
+ /** Unique identifier for this event type. Conventionally versioned (e.g., `v1.TodoCreated`). */
34
+ name: TName
35
+
36
+ /** Effect Schema used for validating and encoding/decoding event arguments. */
37
+ schema: Schema.Schema<TType, TEncoded>
38
+
39
+ options: {
40
+ /**
41
+ * When true, the event is only synced within the same client's sessions (e.g., across tabs)
42
+ * but never sent to the sync backend. Useful for UI state like selected items or filters.
43
+ */
44
+ clientOnly: boolean
45
+
46
+ /**
47
+ * Callback defining fact constraints for this event.
48
+ * @experimental This feature is not fully implemented yet.
49
+ */
50
+ facts: FactsCallback<TType> | undefined
51
+
52
+ /** Whether this is a derived event. Derived events cannot have materializers. */
53
+ derived: TDerived
54
+
55
+ /**
56
+ * Deprecation reason for this event. When set, a warning is logged at commit time.
57
+ */
58
+ deprecated: string | undefined
59
+ }
60
+
61
+ /**
62
+ * Callable signature - creates a partial event with decoded arguments.
63
+ * The returned object can be passed directly to `store.commit()`.
64
+ */
65
+ (
66
+ args: TType,
67
+ ): {
68
+ name: TName
69
+ args: TType
70
+ }
71
+
72
+ /**
73
+ * Creates a partial event with pre-encoded arguments.
74
+ * Useful when working with already-serialized data.
75
+ */
76
+ encoded: (args: TEncoded) => {
77
+ name: TName
78
+ args: TEncoded
79
+ }
80
+
81
+ /** Type helper for accessing the event's shape with name and decoded args. */
82
+ readonly Event: {
83
+ name: TName
84
+ args: TType
85
+ }
86
+ }
87
+
88
+ export namespace EventDef {
89
+ /**
90
+ * Wildcard type matching any EventDef regardless of type parameters.
91
+ * Used as a type constraint in generic functions and collections.
92
+ */
93
+ export type Any = EventDef<string, any, any, boolean>
94
+
95
+ /**
96
+ * EventDef without the callable function signature.
97
+ * Used in contexts where only the metadata (name, schema, options) is needed,
98
+ * such as materializer definitions.
99
+ */
100
+ export type AnyWithoutFn = Pick<Any, 'name' | 'schema' | 'options'>
101
+ }
102
+
103
+ /**
104
+ * Container holding a Map of event definitions keyed by name.
105
+ * Used internally by LiveStoreSchema.
106
+ */
107
+ export type EventDefMap = {
108
+ map: Map<string, EventDef.Any>
109
+ }
110
+
111
+ /**
112
+ * Plain object record of event definitions keyed by name.
113
+ * This is the typical shape when defining events in user code.
114
+ *
115
+ * @example
116
+ * ```ts
117
+ * const events = {
118
+ * todoCreated: Events.synced({ name: 'v1.TodoCreated', schema: ... }),
119
+ * todoDeleted: Events.synced({ name: 'v1.TodoDeleted', schema: ... }),
120
+ * } satisfies EventDefRecord
121
+ * ```
122
+ */
123
+ export type EventDefRecord = {
124
+ [name: string]: EventDef.Any
125
+ }
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Facts System for Event Constraints (Experimental)
3
+ *
4
+ * The facts system enables defining constraints and dependencies between events.
5
+ * Facts are key-value pairs that events can read, set, or require, allowing
6
+ * LiveStore to understand event relationships for:
7
+ * - History constraints (ordering requirements)
8
+ * - Event compaction (which events can be safely merged)
9
+ * - Conflict detection during sync
10
+ *
11
+ * @experimental This system is not fully implemented yet.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * const facts = defineFacts({
16
+ * todoExists: (id: string) => [`todo:${id}`, true],
17
+ * userOwns: (userId: string, todoId: string) => [`owns:${userId}:${todoId}`, true],
18
+ * })
19
+ *
20
+ * const todoCreated = Events.synced({
21
+ * name: 'v1.TodoCreated',
22
+ * schema: Schema.Struct({ id: Schema.String, userId: Schema.String }),
23
+ * facts: ({ id, userId }) => ({
24
+ * modify: { set: [facts.todoExists(id), facts.userOwns(userId, id)] },
25
+ * require: [],
26
+ * }),
27
+ * })
28
+ * ```
29
+ * @module
30
+ */
31
+
32
+ /** String key identifying a fact (e.g., `"todo:abc123"` or `"user:owner:xyz"`). */
33
+ export type EventDefKey = string
34
+
35
+ /** String identifier for a fact type. */
36
+ export type EventDefFact = string
37
+
38
+ /** Immutable map of fact keys to their current values. */
39
+ export type EventDefFacts = ReadonlyMap<string, any>
40
+
41
+ /**
42
+ * Groups of facts that an event interacts with.
43
+ * Used internally to track how events modify and depend on facts.
44
+ */
45
+ export type EventDefFactsGroup = {
46
+ /** Facts this event sets to a new value. */
47
+ modifySet: EventDefFacts
48
+
49
+ /** Facts this event removes/unsets. */
50
+ modifyUnset: EventDefFacts
51
+
52
+ /**
53
+ * Facts this event requires to exist with specific values.
54
+ * Events on independent dependency branches are commutative,
55
+ * which can facilitate more prioritized syncing.
56
+ */
57
+ depRequire: EventDefFacts
58
+
59
+ /** Facts this event reads (but doesn't require). */
60
+ depRead: EventDefFacts
61
+ }
62
+
63
+ /** Mutable snapshot of facts state at a point in time. */
64
+ export type EventDefFactsSnapshot = Map<string, any>
65
+
66
+ /**
67
+ * Input format for specifying a fact.
68
+ * Either a simple key string (value defaults to `true`) or a `[key, value]` tuple.
69
+ *
70
+ * @example
71
+ * ```ts
72
+ * // Simple key (value = true)
73
+ * const fact1: EventDefFactInput = 'todo:abc123'
74
+ *
75
+ * // Key-value tuple
76
+ * const fact2: EventDefFactInput = ['todo:abc123', { status: 'active' }]
77
+ * ```
78
+ */
79
+ export type EventDefFactInput = string | readonly [string, any]
80
+
81
+ /**
82
+ * Callback function that defines how an event interacts with the facts system.
83
+ * Called during event processing to determine fact constraints.
84
+ *
85
+ * @example
86
+ * ```ts
87
+ * const factsCallback: FactsCallback<{ id: string }> = (args, currentFacts) => ({
88
+ * modify: {
89
+ * set: [`item:${args.id}`], // Create/update this fact
90
+ * unset: [], // No facts to remove
91
+ * },
92
+ * require: currentFacts.has('initialized') ? [] : ['initialized'],
93
+ * })
94
+ * ```
95
+ */
96
+ export type FactsCallback<TTo> = (
97
+ args: TTo,
98
+ currentFacts: EventDefFacts,
99
+ ) => {
100
+ modify: {
101
+ /** Facts to set (create or update). */
102
+ set: Iterable<EventDefFactInput>
103
+ /** Facts to unset (remove). */
104
+ unset: Iterable<EventDefFactInput>
105
+ }
106
+ /** Facts that must exist with specific values for this event to be valid. */
107
+ require: Iterable<EventDefFactInput>
108
+ }
109
+
110
+ /**
111
+ * Helper to define a typed record of fact constructors.
112
+ * Returns the input unchanged but provides type inference.
113
+ *
114
+ * @example
115
+ * ```ts
116
+ * const facts = defineFacts({
117
+ * // Simple fact (value = true)
118
+ * initialized: 'system:initialized',
119
+ *
120
+ * // Parameterized fact constructor
121
+ * todoExists: (id: string) => [`todo:${id}`, true] as const,
122
+ *
123
+ * // Fact with complex value
124
+ * todoStatus: (id: string, status: string) => [`todo:${id}:status`, status] as const,
125
+ * })
126
+ *
127
+ * // Usage
128
+ * facts.todoExists('abc') // => ['todo:abc', true]
129
+ * ```
130
+ */
131
+ export const defineFacts = <
132
+ TRecord extends Record<string, EventDefFactInput | ((...args: any[]) => EventDefFactInput)>,
133
+ >(
134
+ record: TRecord,
135
+ ): TRecord => record
@@ -0,0 +1,172 @@
1
+ /**
2
+ * Materializer System
3
+ *
4
+ * Materializers transform events into SQL mutations (INSERT, UPDATE, DELETE).
5
+ * Every non-derived event must have a corresponding materializer that defines
6
+ * how it affects the SQLite database state.
7
+ *
8
+ * Materializers are pure functions that receive the event arguments and return
9
+ * SQL operations. They can also query current state when needed for complex
10
+ * transformations.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { State } from '@livestore/livestore'
15
+ *
16
+ * const materializers = State.SQLite.materializers(events, {
17
+ * 'v1.TodoCreated': ({ id, text }) =>
18
+ * tables.todos.insert({ id, text, completed: false }),
19
+ *
20
+ * 'v1.TodoCompleted': ({ id }) =>
21
+ * tables.todos.update({ completed: true }).where({ id }),
22
+ *
23
+ * 'v1.TodoDeleted': ({ id, deletedAt }) =>
24
+ * tables.todos.update({ deletedAt }).where({ id }),
25
+ * })
26
+ * ```
27
+ * @module
28
+ */
29
+
30
+ import type { SingleOrReadonlyArray } from '@livestore/utils'
31
+
32
+ import type { BindValues } from '../../sql-queries/sql-queries.ts'
33
+ import type { ParamsObject } from '../../util.ts'
34
+ import type * as LiveStoreEvent from '../LiveStoreEvent/mod.ts'
35
+ import type { QueryBuilder } from '../state/sqlite/query-builder/mod.ts'
36
+ import type { EventDef } from './event-def.ts'
37
+ import type { EventDefFacts } from './facts.ts'
38
+
39
+ /**
40
+ * Result type for materializer functions.
41
+ *
42
+ * Can be one of:
43
+ * - A QueryBuilder operation (recommended for type safety)
44
+ * - A raw SQL string
45
+ * - An object with SQL, bind values, and optional write table tracking
46
+ */
47
+ export type MaterializerResult =
48
+ | {
49
+ sql: string
50
+ bindValues: BindValues
51
+ writeTables?: ReadonlySet<string>
52
+ }
53
+ | QueryBuilder.Any
54
+ | string
55
+
56
+ /**
57
+ * Function signature for querying current state within a materializer.
58
+ *
59
+ * Allows materializers to read existing data when computing mutations.
60
+ * Can be called with either raw SQL or a type-safe QueryBuilder.
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * 'v1.TodoUpdated': ({ id, text }, { query }) => {
65
+ * const existing = query(tables.todos.select().where({ id }).first())
66
+ * if (!existing) return [] // No-op if todo doesn't exist
67
+ * return tables.todos.update({ text }).where({ id })
68
+ * }
69
+ * ```
70
+ */
71
+ export type MaterializerContextQuery = {
72
+ /** Query with raw SQL and bind values. */
73
+ (args: { query: string; bindValues: ParamsObject }): ReadonlyArray<unknown>
74
+ /** Query with a type-safe QueryBuilder. */
75
+ <TResult>(qb: QueryBuilder<TResult, any, any>): TResult
76
+ }
77
+
78
+ /**
79
+ * Function type for transforming an event into database mutations.
80
+ *
81
+ * Materializers are the bridge between events and SQLite state. They receive
82
+ * the decoded event arguments and return SQL operations to execute.
83
+ *
84
+ * @example
85
+ * ```ts
86
+ * const todoCreatedMaterializer: Materializer<typeof todoCreated> =
87
+ * ({ id, text }) => tables.todos.insert({ id, text, completed: false })
88
+ * ```
89
+ */
90
+ export type Materializer<TEventDef extends EventDef.AnyWithoutFn = EventDef.AnyWithoutFn> = (
91
+ /** Decoded event arguments. */
92
+ event: TEventDef['schema']['Type'],
93
+ context: {
94
+ /** Current facts state (experimental). */
95
+ currentFacts: EventDefFacts
96
+ /** The event definition being materialized. */
97
+ eventDef: TEventDef
98
+ /** Function to query current database state. */
99
+ query: MaterializerContextQuery
100
+ /** Full event metadata including clientId, sessionId, sequence numbers. */
101
+ event: LiveStoreEvent.Client.Decoded
102
+ },
103
+ ) => SingleOrReadonlyArray<MaterializerResult>
104
+
105
+ /**
106
+ * Type-safe wrapper for defining a single materializer.
107
+ *
108
+ * Useful when defining materializers separately from the `materializers()` builder.
109
+ * The first argument provides type inference for the second.
110
+ *
111
+ * @example
112
+ * ```ts
113
+ * const todoCreatedHandler = defineMaterializer(
114
+ * events.todoCreated,
115
+ * ({ id, text }) => tables.todos.insert({ id, text, completed: false })
116
+ * )
117
+ * ```
118
+ */
119
+ export const defineMaterializer = <TEventDef extends EventDef.AnyWithoutFn>(
120
+ _eventDef: TEventDef,
121
+ materializer: Materializer<TEventDef>,
122
+ ): Materializer<TEventDef> => {
123
+ return materializer
124
+ }
125
+
126
+ /**
127
+ * Builder function for creating a type-safe materializer map.
128
+ *
129
+ * This is the primary way to define materializers in LiveStore. It ensures:
130
+ * - Every non-derived event has a corresponding materializer
131
+ * - Materializer argument types match their event schemas
132
+ * - Derived events are excluded from the required handlers
133
+ *
134
+ * @example
135
+ * ```ts
136
+ * import { State } from '@livestore/livestore'
137
+ *
138
+ * const handlers = State.SQLite.materializers(events, {
139
+ * // Handler for each event - argument types are inferred
140
+ * 'v1.TodoCreated': ({ id, text, completed }) =>
141
+ * tables.todos.insert({ id, text, completed }),
142
+ *
143
+ * 'v1.TodoUpdated': ({ id, text }) =>
144
+ * tables.todos.update({ text }).where({ id }),
145
+ *
146
+ * // Can return multiple operations
147
+ * 'v1.UserCreatedWithDefaults': ({ userId, name }) => [
148
+ * tables.users.insert({ id: userId, name }),
149
+ * tables.settings.insert({ userId, theme: 'light' }),
150
+ * ],
151
+ *
152
+ * // Can query current state
153
+ * 'v1.TodoToggled': ({ id }, { query }) => {
154
+ * const todo = query(tables.todos.select().where({ id }).first())
155
+ * return tables.todos.update({ completed: !todo?.completed }).where({ id })
156
+ * },
157
+ * })
158
+ * ```
159
+ */
160
+ export const materializers = <TInputRecord extends Record<string, EventDef.AnyWithoutFn>>(
161
+ _eventDefRecord: TInputRecord,
162
+ handlers: {
163
+ [TEventName in TInputRecord[keyof TInputRecord]['name'] as Extract<
164
+ TInputRecord[keyof TInputRecord],
165
+ { name: TEventName }
166
+ >['options']['derived'] extends true
167
+ ? never
168
+ : TEventName]: Materializer<Extract<TInputRecord[keyof TInputRecord], { name: TEventName }>>
169
+ },
170
+ ) => {
171
+ return handlers
172
+ }
@@ -0,0 +1,5 @@
1
+ export * from './define.ts'
2
+ export * from './deprecated.ts'
3
+ export * from './event-def.ts'
4
+ export * from './facts.ts'
5
+ export * from './materializer.ts'
@@ -0,0 +1,257 @@
1
+ import { Brand, Schema as S } from '@livestore/utils/effect'
2
+
3
+ import { type Type as Global, Schema as GlobalSchema, make as makeGlobal } from './global.ts'
4
+
5
+ /** Branded integer type for client-local sequence numbers. */
6
+ export type Type = Brand.Branded<number, 'ClientEventSequenceNumber'>
7
+
8
+ const ClientBrand = Brand.nominal<Type>()
9
+
10
+ /** Effect Schema for encoding/decoding client sequence numbers. */
11
+ export const Schema = S.fromBrand(ClientBrand)(S.Int)
12
+
13
+ /**
14
+ * Creates a branded client sequence number from a plain number.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * const clientSeq = EventSequenceNumber.Client.make(1)
19
+ * ```
20
+ */
21
+ export const make = ClientBrand
22
+
23
+ /**
24
+ * Default client sequence number (0). Used for confirmed/synced events.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * const defaultSeq = EventSequenceNumber.Client.DEFAULT // 0
29
+ * ```
30
+ */
31
+ export const DEFAULT = make(0)
32
+
33
+ /** Default rebase generation (0). Increments each time the client rebases unconfirmed events. */
34
+ export const REBASE_GENERATION_DEFAULT = 0
35
+
36
+ /**
37
+ * Composite event sequence number consisting of global + client + rebaseGeneration.
38
+ * Used for client-side event tracking with support for unconfirmed local events.
39
+ *
40
+ * For event notation documentation, see: contributor-docs/events-notation.md
41
+ */
42
+ export type Composite = {
43
+ global: Global
44
+ client: Type
45
+ /**
46
+ * Generation integer that is incremented whenever the client rebased.
47
+ * Remains constant for all subsequent events until another rebase occurs.
48
+ */
49
+ rebaseGeneration: number
50
+ }
51
+
52
+ /** Input type for creating a Composite sequence number. Allows omitting rebaseGeneration (defaults to 0). */
53
+ export type CompositeInput =
54
+ | Composite
55
+ | (Omit<typeof CompositeSchema.Encoded, 'rebaseGeneration'> & { rebaseGeneration?: number })
56
+
57
+ /** A pair of sequence numbers representing an event and its parent. */
58
+ export type CompositePair = { seqNum: Composite; parentSeqNum: Composite }
59
+
60
+ /**
61
+ * Compare two composite sequence numbers.
62
+ * Comparison hierarchy: global > client > rebaseGeneration
63
+ */
64
+ export const compare = (a: Composite, b: Composite) => {
65
+ if (a.global !== b.global) {
66
+ return a.global - b.global
67
+ }
68
+ if (a.client !== b.client) {
69
+ return a.client - b.client
70
+ }
71
+ return a.rebaseGeneration - b.rebaseGeneration
72
+ }
73
+
74
+ /**
75
+ * Convert a composite sequence number to a string representation.
76
+ *
77
+ * For notation documentation, see: contributor-docs/events-notation.md
78
+ */
79
+ export const toString = (seqNum: Composite) => {
80
+ const rebaseGenerationStr = seqNum.rebaseGeneration > 0 ? `r${seqNum.rebaseGeneration}` : ''
81
+ return seqNum.client === 0
82
+ ? `e${seqNum.global}${rebaseGenerationStr}`
83
+ : `e${seqNum.global}.${seqNum.client}${rebaseGenerationStr}`
84
+ }
85
+
86
+ /**
87
+ * Convert a string representation of a sequence number to a Composite.
88
+ * Parses strings in the format: e{global}[.{client}][r{rebaseGeneration}]
89
+ * Examples: "e0", "e0r1", "e0.1", "e0.1r1"
90
+ *
91
+ * For full notation documentation, see: contributor-docs/events-notation.md
92
+ */
93
+ export const fromString = (str: string): Composite => {
94
+ if (str.startsWith('e') === false) {
95
+ throw new Error('Invalid event sequence number string: must start with "e"')
96
+ }
97
+
98
+ // Remove the 'e' prefix
99
+ const remaining = str.slice(1)
100
+
101
+ // Parse rebase generation if present
102
+ let rebaseGeneration = REBASE_GENERATION_DEFAULT
103
+ let withoutRebase = remaining
104
+ const rebaseMatch = remaining.match(/r(\d+)$/)
105
+ if (rebaseMatch !== null) {
106
+ rebaseGeneration = Number.parseInt(rebaseMatch[1]!, 10)
107
+ withoutRebase = remaining.slice(0, -rebaseMatch[0].length)
108
+ }
109
+
110
+ // Parse global and client parts
111
+ const parts = withoutRebase.split('.')
112
+
113
+ // Validate that parts contain only digits (and possibly empty for client)
114
+ if (parts[0] === '' || /^\d+$/.test(parts[0]!) === false) {
115
+ throw new Error('Invalid event sequence number string: invalid number format')
116
+ }
117
+
118
+ if (parts.length > 1 && parts[1] !== undefined && (parts[1] === '' || /^\d+$/.test(parts[1]) === false)) {
119
+ throw new Error('Invalid event sequence number string: invalid number format')
120
+ }
121
+
122
+ const global = Number.parseInt(parts[0]!, 10)
123
+ const client = parts.length > 1 && parts[1] !== undefined ? Number.parseInt(parts[1], 10) : 0
124
+
125
+ if (Number.isNaN(global) === true || Number.isNaN(client) === true || Number.isNaN(rebaseGeneration) === true) {
126
+ throw new TypeError('Invalid event sequence number string: invalid number format')
127
+ }
128
+
129
+ return {
130
+ global: makeGlobal(global),
131
+ client: make(client),
132
+ rebaseGeneration,
133
+ }
134
+ }
135
+
136
+ /** Creates a Composite sequence number from a global sequence number (client=0, rebaseGeneration=0). */
137
+ export const fromGlobal = (seqNum: Global): Composite => ({
138
+ global: seqNum,
139
+ client: DEFAULT,
140
+ rebaseGeneration: REBASE_GENERATION_DEFAULT,
141
+ })
142
+
143
+ /** Returns true if two Composite sequence numbers are structurally equal. */
144
+ export const isEqual = (a: Composite, b: Composite) =>
145
+ a.global === b.global && a.client === b.client && a.rebaseGeneration === b.rebaseGeneration
146
+
147
+ /** Returns true if `a` is strictly greater than `b` (compares global, then client). */
148
+ export const isGreaterThan = (a: Composite, b: Composite) => {
149
+ return a.global > b.global || (a.global === b.global && a.client > b.client)
150
+ }
151
+
152
+ /** Returns true if `a` is greater than or equal to `b` (compares global, then client). */
153
+ export const isGreaterThanOrEqual = (a: Composite, b: Composite) => {
154
+ return a.global > b.global || (a.global === b.global && a.client >= b.client)
155
+ }
156
+
157
+ /** Returns the larger of two Composite sequence numbers. */
158
+ export const max = (a: Composite, b: Composite) => {
159
+ return a.global > b.global || (a.global === b.global && a.client > b.client) ? a : b
160
+ }
161
+
162
+ /** Returns the difference between two Composite sequence numbers (a - b) for global and client components. */
163
+ export const diff = (a: Composite, b: Composite) => {
164
+ return {
165
+ global: a.global - b.global,
166
+ client: a.client - b.client,
167
+ }
168
+ }
169
+
170
+ /**
171
+ * Schema for the composite event sequence number.
172
+ * NOTE: Client mutation events with a non-0 client id won't be synced to the sync backend.
173
+ */
174
+ const CompositeSchema = S.Struct({
175
+ global: GlobalSchema,
176
+ /** Only increments for client-local events */
177
+ client: Schema,
178
+ // Client only
179
+ rebaseGeneration: S.Int,
180
+ }).annotations({
181
+ title: 'EventSequenceNumber.Composite',
182
+ pretty: () => (seqNum) => toString(seqNum),
183
+ })
184
+
185
+ /**
186
+ * Creates a validated Composite sequence number from input.
187
+ * If rebaseGeneration is omitted, defaults to REBASE_GENERATION_DEFAULT (0).
188
+ */
189
+ const makeComposite = (seqNum: CompositeInput): Composite => {
190
+ return S.is(CompositeSchema)(seqNum) === true
191
+ ? seqNum
192
+ : S.decodeSync(CompositeSchema)({
193
+ ...seqNum,
194
+ rebaseGeneration: seqNum.rebaseGeneration ?? REBASE_GENERATION_DEFAULT,
195
+ })
196
+ }
197
+
198
+ /**
199
+ * Effect Schema for the composite event sequence number (global + client + rebaseGeneration).
200
+ * Also includes a `make` helper for creating validated Composite values.
201
+ *
202
+ * @example
203
+ * ```ts
204
+ * const seqNum: EventSequenceNumber.Client.Composite = {
205
+ * global: EventSequenceNumber.Global.make(5),
206
+ * client: EventSequenceNumber.Client.DEFAULT,
207
+ * rebaseGeneration: 0
208
+ * }
209
+ *
210
+ * const validated = EventSequenceNumber.Client.Composite.make({ global: 5, client: 0, rebaseGeneration: 0 })
211
+ * ```
212
+ */
213
+ export const Composite = Object.assign(CompositeSchema, { make: makeComposite })
214
+
215
+ /** The root sequence number (global=0, client=0, rebaseGeneration=0). Parent of the first event. */
216
+ export const ROOT = {
217
+ global: makeGlobal(0),
218
+ client: DEFAULT,
219
+ rebaseGeneration: REBASE_GENERATION_DEFAULT,
220
+ } satisfies Composite
221
+
222
+ /**
223
+ * Computes the next sequence number and its parent based on the current position.
224
+ *
225
+ * For client-local events (isClient=true): increments the client component, keeps global.
226
+ * For global events (isClient=false): increments global, resets client to 0.
227
+ */
228
+ export const nextPair = ({
229
+ seqNum,
230
+ isClient,
231
+ rebaseGeneration,
232
+ }: {
233
+ seqNum: Composite
234
+ isClient: boolean
235
+ rebaseGeneration?: number
236
+ }): CompositePair => {
237
+ if (isClient === true) {
238
+ return {
239
+ seqNum: {
240
+ global: seqNum.global,
241
+ client: make(seqNum.client + 1),
242
+ rebaseGeneration: rebaseGeneration ?? seqNum.rebaseGeneration,
243
+ },
244
+ parentSeqNum: seqNum,
245
+ }
246
+ }
247
+
248
+ return {
249
+ seqNum: {
250
+ global: makeGlobal(seqNum.global + 1),
251
+ client: DEFAULT,
252
+ rebaseGeneration: rebaseGeneration ?? seqNum.rebaseGeneration,
253
+ },
254
+ // NOTE we always point to `client: 0` for non-client-local events
255
+ parentSeqNum: { global: seqNum.global, client: DEFAULT, rebaseGeneration: seqNum.rebaseGeneration },
256
+ }
257
+ }