@livestore/common 0.4.0-dev.8 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (518) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/ClientSessionLeaderThreadProxy.d.ts +27 -12
  3. package/dist/ClientSessionLeaderThreadProxy.d.ts.map +1 -1
  4. package/dist/ClientSessionLeaderThreadProxy.js.map +1 -1
  5. package/dist/WorkerTransportError.d.ts +11 -0
  6. package/dist/WorkerTransportError.d.ts.map +1 -0
  7. package/dist/WorkerTransportError.js +11 -0
  8. package/dist/WorkerTransportError.js.map +1 -0
  9. package/dist/adapter-types.d.ts +37 -7
  10. package/dist/adapter-types.d.ts.map +1 -1
  11. package/dist/adapter-types.js +27 -1
  12. package/dist/adapter-types.js.map +1 -1
  13. package/dist/bounded-collections.d.ts.map +1 -1
  14. package/dist/bounded-collections.js +6 -4
  15. package/dist/bounded-collections.js.map +1 -1
  16. package/dist/debug-info.d.ts.map +1 -1
  17. package/dist/debug-info.js +33 -6
  18. package/dist/debug-info.js.map +1 -1
  19. package/dist/devtools/devtools-compatibility.test.d.ts +2 -0
  20. package/dist/devtools/devtools-compatibility.test.d.ts.map +1 -0
  21. package/dist/devtools/devtools-compatibility.test.js +15 -0
  22. package/dist/devtools/devtools-compatibility.test.js.map +1 -0
  23. package/dist/devtools/devtools-messages-client-session.d.ts +55 -24
  24. package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -1
  25. package/dist/devtools/devtools-messages-client-session.js +22 -5
  26. package/dist/devtools/devtools-messages-client-session.js.map +1 -1
  27. package/dist/devtools/devtools-messages-common.d.ts +11 -14
  28. package/dist/devtools/devtools-messages-common.d.ts.map +1 -1
  29. package/dist/devtools/devtools-messages-common.js +7 -9
  30. package/dist/devtools/devtools-messages-common.js.map +1 -1
  31. package/dist/devtools/devtools-messages-leader.d.ts +65 -30
  32. package/dist/devtools/devtools-messages-leader.d.ts.map +1 -1
  33. package/dist/devtools/devtools-messages-leader.js +29 -11
  34. package/dist/devtools/devtools-messages-leader.js.map +1 -1
  35. package/dist/devtools/devtools-sessioninfo.d.ts +14 -2
  36. package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -1
  37. package/dist/devtools/devtools-sessioninfo.js +7 -4
  38. package/dist/devtools/devtools-sessioninfo.js.map +1 -1
  39. package/dist/devtools/mod.d.ts +13 -2
  40. package/dist/devtools/mod.d.ts.map +1 -1
  41. package/dist/devtools/mod.js +10 -3
  42. package/dist/devtools/mod.js.map +1 -1
  43. package/dist/errors.d.ts +48 -18
  44. package/dist/errors.d.ts.map +1 -1
  45. package/dist/errors.js +20 -12
  46. package/dist/errors.js.map +1 -1
  47. package/dist/index.d.ts +4 -1
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +4 -1
  50. package/dist/index.js.map +1 -1
  51. package/dist/leader-thread/LeaderSyncProcessor.d.ts +53 -6
  52. package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
  53. package/dist/leader-thread/LeaderSyncProcessor.js +325 -257
  54. package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
  55. package/dist/leader-thread/RejectedPushError.d.ts +107 -0
  56. package/dist/leader-thread/RejectedPushError.d.ts.map +1 -0
  57. package/dist/leader-thread/RejectedPushError.js +78 -0
  58. package/dist/leader-thread/RejectedPushError.js.map +1 -0
  59. package/dist/leader-thread/connection.js +1 -1
  60. package/dist/leader-thread/connection.js.map +1 -1
  61. package/dist/leader-thread/eventlog.d.ts +19 -14
  62. package/dist/leader-thread/eventlog.d.ts.map +1 -1
  63. package/dist/leader-thread/eventlog.js +78 -18
  64. package/dist/leader-thread/eventlog.js.map +1 -1
  65. package/dist/leader-thread/leader-worker-devtools.d.ts +1 -2
  66. package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
  67. package/dist/leader-thread/leader-worker-devtools.js +90 -58
  68. package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
  69. package/dist/leader-thread/make-leader-thread-layer.d.ts +15 -7
  70. package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
  71. package/dist/leader-thread/make-leader-thread-layer.js +49 -17
  72. package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
  73. package/dist/leader-thread/make-leader-thread-layer.test.d.ts +2 -0
  74. package/dist/leader-thread/make-leader-thread-layer.test.d.ts.map +1 -0
  75. package/dist/leader-thread/make-leader-thread-layer.test.js +32 -0
  76. package/dist/leader-thread/make-leader-thread-layer.test.js.map +1 -0
  77. package/dist/leader-thread/materialize-event.d.ts +1 -1
  78. package/dist/leader-thread/materialize-event.d.ts.map +1 -1
  79. package/dist/leader-thread/materialize-event.js +28 -9
  80. package/dist/leader-thread/materialize-event.js.map +1 -1
  81. package/dist/leader-thread/mod.d.ts +1 -0
  82. package/dist/leader-thread/mod.d.ts.map +1 -1
  83. package/dist/leader-thread/mod.js +1 -0
  84. package/dist/leader-thread/mod.js.map +1 -1
  85. package/dist/leader-thread/recreate-db.d.ts +2 -2
  86. package/dist/leader-thread/recreate-db.d.ts.map +1 -1
  87. package/dist/leader-thread/recreate-db.js +6 -6
  88. package/dist/leader-thread/recreate-db.js.map +1 -1
  89. package/dist/leader-thread/shutdown-channel.d.ts +2 -2
  90. package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
  91. package/dist/leader-thread/shutdown-channel.js +2 -2
  92. package/dist/leader-thread/shutdown-channel.js.map +1 -1
  93. package/dist/leader-thread/stream-events.d.ts +56 -0
  94. package/dist/leader-thread/stream-events.d.ts.map +1 -0
  95. package/dist/leader-thread/stream-events.js +167 -0
  96. package/dist/leader-thread/stream-events.js.map +1 -0
  97. package/dist/leader-thread/types.d.ts +95 -17
  98. package/dist/leader-thread/types.d.ts.map +1 -1
  99. package/dist/leader-thread/types.js +13 -0
  100. package/dist/leader-thread/types.js.map +1 -1
  101. package/dist/logging.d.ts +40 -0
  102. package/dist/logging.d.ts.map +1 -0
  103. package/dist/logging.js +33 -0
  104. package/dist/logging.js.map +1 -0
  105. package/dist/make-client-session.d.ts +5 -3
  106. package/dist/make-client-session.d.ts.map +1 -1
  107. package/dist/make-client-session.js +7 -4
  108. package/dist/make-client-session.js.map +1 -1
  109. package/dist/materializer-helper.d.ts +6 -6
  110. package/dist/materializer-helper.d.ts.map +1 -1
  111. package/dist/materializer-helper.js +18 -8
  112. package/dist/materializer-helper.js.map +1 -1
  113. package/dist/otel.d.ts +2 -1
  114. package/dist/otel.d.ts.map +1 -1
  115. package/dist/otel.js +7 -2
  116. package/dist/otel.js.map +1 -1
  117. package/dist/rematerialize-from-eventlog.d.ts +3 -3
  118. package/dist/rematerialize-from-eventlog.d.ts.map +1 -1
  119. package/dist/rematerialize-from-eventlog.js +40 -29
  120. package/dist/rematerialize-from-eventlog.js.map +1 -1
  121. package/dist/schema/EventDef/define.d.ts +161 -0
  122. package/dist/schema/EventDef/define.d.ts.map +1 -0
  123. package/dist/schema/EventDef/define.js +140 -0
  124. package/dist/schema/EventDef/define.js.map +1 -0
  125. package/dist/schema/EventDef/deprecated.d.ts +99 -0
  126. package/dist/schema/EventDef/deprecated.d.ts.map +1 -0
  127. package/dist/schema/EventDef/deprecated.js +144 -0
  128. package/dist/schema/EventDef/deprecated.js.map +1 -0
  129. package/dist/schema/EventDef/deprecated.test.d.ts +2 -0
  130. package/dist/schema/EventDef/deprecated.test.d.ts.map +1 -0
  131. package/dist/schema/EventDef/deprecated.test.js +95 -0
  132. package/dist/schema/EventDef/deprecated.test.js.map +1 -0
  133. package/dist/schema/EventDef/event-def.d.ts +110 -0
  134. package/dist/schema/EventDef/event-def.d.ts.map +1 -0
  135. package/dist/schema/EventDef/event-def.js +2 -0
  136. package/dist/schema/EventDef/event-def.js.map +1 -0
  137. package/dist/schema/EventDef/facts.d.ts +118 -0
  138. package/dist/schema/EventDef/facts.d.ts.map +1 -0
  139. package/dist/schema/EventDef/facts.js +53 -0
  140. package/dist/schema/EventDef/facts.js.map +1 -0
  141. package/dist/schema/EventDef/materializer.d.ts +155 -0
  142. package/dist/schema/EventDef/materializer.d.ts.map +1 -0
  143. package/dist/schema/EventDef/materializer.js +83 -0
  144. package/dist/schema/EventDef/materializer.js.map +1 -0
  145. package/dist/schema/EventDef/mod.d.ts +6 -0
  146. package/dist/schema/EventDef/mod.d.ts.map +1 -0
  147. package/dist/schema/EventDef/mod.js +6 -0
  148. package/dist/schema/EventDef/mod.js.map +1 -0
  149. package/dist/schema/EventSequenceNumber/client.d.ts +136 -0
  150. package/dist/schema/EventSequenceNumber/client.d.ts.map +1 -0
  151. package/dist/schema/EventSequenceNumber/client.js +193 -0
  152. package/dist/schema/EventSequenceNumber/client.js.map +1 -0
  153. package/dist/schema/EventSequenceNumber/global.d.ts +15 -0
  154. package/dist/schema/EventSequenceNumber/global.d.ts.map +1 -0
  155. package/dist/schema/EventSequenceNumber/global.js +14 -0
  156. package/dist/schema/EventSequenceNumber/global.js.map +1 -0
  157. package/dist/schema/EventSequenceNumber/mod.d.ts +37 -0
  158. package/dist/schema/EventSequenceNumber/mod.d.ts.map +1 -0
  159. package/dist/schema/EventSequenceNumber/mod.js +37 -0
  160. package/dist/schema/EventSequenceNumber/mod.js.map +1 -0
  161. package/dist/schema/EventSequenceNumber.test.js +44 -44
  162. package/dist/schema/EventSequenceNumber.test.js.map +1 -1
  163. package/dist/schema/{LiveStoreEvent.d.ts → LiveStoreEvent/client.d.ts} +102 -111
  164. package/dist/schema/LiveStoreEvent/client.d.ts.map +1 -0
  165. package/dist/schema/LiveStoreEvent/client.js +176 -0
  166. package/dist/schema/LiveStoreEvent/client.js.map +1 -0
  167. package/dist/schema/LiveStoreEvent/client.test.d.ts +2 -0
  168. package/dist/schema/LiveStoreEvent/client.test.d.ts.map +1 -0
  169. package/dist/schema/LiveStoreEvent/client.test.js +111 -0
  170. package/dist/schema/LiveStoreEvent/client.test.js.map +1 -0
  171. package/dist/schema/LiveStoreEvent/for-event-def.d.ts +52 -0
  172. package/dist/schema/LiveStoreEvent/for-event-def.d.ts.map +1 -0
  173. package/dist/schema/LiveStoreEvent/for-event-def.js +2 -0
  174. package/dist/schema/LiveStoreEvent/for-event-def.js.map +1 -0
  175. package/dist/schema/LiveStoreEvent/global.d.ts +36 -0
  176. package/dist/schema/LiveStoreEvent/global.d.ts.map +1 -0
  177. package/dist/schema/LiveStoreEvent/global.js +31 -0
  178. package/dist/schema/LiveStoreEvent/global.js.map +1 -0
  179. package/dist/schema/LiveStoreEvent/input.d.ts +46 -0
  180. package/dist/schema/LiveStoreEvent/input.d.ts.map +1 -0
  181. package/dist/schema/LiveStoreEvent/input.js +26 -0
  182. package/dist/schema/LiveStoreEvent/input.js.map +1 -0
  183. package/dist/schema/LiveStoreEvent/mod.d.ts +5 -0
  184. package/dist/schema/LiveStoreEvent/mod.d.ts.map +1 -0
  185. package/dist/schema/LiveStoreEvent/mod.js +5 -0
  186. package/dist/schema/LiveStoreEvent/mod.js.map +1 -0
  187. package/dist/schema/events.d.ts +1 -1
  188. package/dist/schema/events.d.ts.map +1 -1
  189. package/dist/schema/events.js +1 -1
  190. package/dist/schema/events.js.map +1 -1
  191. package/dist/schema/mod.d.ts +6 -4
  192. package/dist/schema/mod.d.ts.map +1 -1
  193. package/dist/schema/mod.js +5 -4
  194. package/dist/schema/mod.js.map +1 -1
  195. package/dist/schema/schema.d.ts +16 -1
  196. package/dist/schema/schema.d.ts.map +1 -1
  197. package/dist/schema/schema.js +32 -4
  198. package/dist/schema/schema.js.map +1 -1
  199. package/dist/schema/state/sqlite/client-document-def.d.ts +2 -1
  200. package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -1
  201. package/dist/schema/state/sqlite/client-document-def.js +36 -15
  202. package/dist/schema/state/sqlite/client-document-def.js.map +1 -1
  203. package/dist/schema/state/sqlite/client-document-def.test.js +121 -2
  204. package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -1
  205. package/dist/schema/state/sqlite/column-annotations.d.ts.map +1 -1
  206. package/dist/schema/state/sqlite/column-annotations.js +1 -1
  207. package/dist/schema/state/sqlite/column-annotations.js.map +1 -1
  208. package/dist/schema/state/sqlite/column-annotations.test.js +2 -2
  209. package/dist/schema/state/sqlite/column-annotations.test.js.map +1 -1
  210. package/dist/schema/state/sqlite/column-def.d.ts.map +1 -1
  211. package/dist/schema/state/sqlite/column-def.js +96 -47
  212. package/dist/schema/state/sqlite/column-def.js.map +1 -1
  213. package/dist/schema/state/sqlite/column-def.test.js +51 -12
  214. package/dist/schema/state/sqlite/column-def.test.js.map +1 -1
  215. package/dist/schema/state/sqlite/column-spec.d.ts.map +1 -1
  216. package/dist/schema/state/sqlite/column-spec.js +30 -12
  217. package/dist/schema/state/sqlite/column-spec.js.map +1 -1
  218. package/dist/schema/state/sqlite/column-spec.test.js +24 -15
  219. package/dist/schema/state/sqlite/column-spec.test.js.map +1 -1
  220. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js +2 -2
  221. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js.map +1 -1
  222. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts +16 -10
  223. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts.map +1 -1
  224. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js +15 -4
  225. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js.map +1 -1
  226. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js +1 -1
  227. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js.map +1 -1
  228. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts +1 -1
  229. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts.map +1 -1
  230. package/dist/schema/state/sqlite/db-schema/dsl/mod.js +1 -1
  231. package/dist/schema/state/sqlite/db-schema/dsl/mod.js.map +1 -1
  232. package/dist/schema/state/sqlite/mod.d.ts +2 -2
  233. package/dist/schema/state/sqlite/mod.d.ts.map +1 -1
  234. package/dist/schema/state/sqlite/mod.js +5 -7
  235. package/dist/schema/state/sqlite/mod.js.map +1 -1
  236. package/dist/schema/state/sqlite/query-builder/api.d.ts +51 -22
  237. package/dist/schema/state/sqlite/query-builder/api.d.ts.map +1 -1
  238. package/dist/schema/state/sqlite/query-builder/astToSql.d.ts.map +1 -1
  239. package/dist/schema/state/sqlite/query-builder/astToSql.js +99 -22
  240. package/dist/schema/state/sqlite/query-builder/astToSql.js.map +1 -1
  241. package/dist/schema/state/sqlite/query-builder/impl.d.ts +1 -1
  242. package/dist/schema/state/sqlite/query-builder/impl.d.ts.map +1 -1
  243. package/dist/schema/state/sqlite/query-builder/impl.js +28 -15
  244. package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -1
  245. package/dist/schema/state/sqlite/query-builder/impl.test.js +231 -93
  246. package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -1
  247. package/dist/schema/state/sqlite/schema-helpers.d.ts +2 -2
  248. package/dist/schema/state/sqlite/schema-helpers.d.ts.map +1 -1
  249. package/dist/schema/state/sqlite/schema-helpers.js +24 -14
  250. package/dist/schema/state/sqlite/schema-helpers.js.map +1 -1
  251. package/dist/schema/state/sqlite/schema-helpers.test.d.ts +2 -0
  252. package/dist/schema/state/sqlite/schema-helpers.test.d.ts.map +1 -0
  253. package/dist/schema/state/sqlite/schema-helpers.test.js +36 -0
  254. package/dist/schema/state/sqlite/schema-helpers.test.js.map +1 -0
  255. package/dist/schema/state/sqlite/{system-tables.d.ts → system-tables/eventlog-tables.d.ts} +21 -450
  256. package/dist/schema/state/sqlite/system-tables/eventlog-tables.d.ts.map +1 -0
  257. package/dist/schema/state/sqlite/system-tables/eventlog-tables.js +54 -0
  258. package/dist/schema/state/sqlite/system-tables/eventlog-tables.js.map +1 -0
  259. package/dist/schema/state/sqlite/system-tables/mod.d.ts +3 -0
  260. package/dist/schema/state/sqlite/system-tables/mod.d.ts.map +1 -0
  261. package/dist/schema/state/sqlite/system-tables/mod.js +3 -0
  262. package/dist/schema/state/sqlite/system-tables/mod.js.map +1 -0
  263. package/dist/schema/state/sqlite/system-tables/state-tables.d.ts +456 -0
  264. package/dist/schema/state/sqlite/system-tables/state-tables.d.ts.map +1 -0
  265. package/dist/schema/state/sqlite/system-tables/state-tables.js +55 -0
  266. package/dist/schema/state/sqlite/system-tables/state-tables.js.map +1 -0
  267. package/dist/schema/state/sqlite/table-def.d.ts +5 -3
  268. package/dist/schema/state/sqlite/table-def.d.ts.map +1 -1
  269. package/dist/schema/state/sqlite/table-def.js +1 -1
  270. package/dist/schema/state/sqlite/table-def.js.map +1 -1
  271. package/dist/schema/state/sqlite/table-def.test.js +92 -3
  272. package/dist/schema/state/sqlite/table-def.test.js.map +1 -1
  273. package/dist/schema/unknown-events.d.ts +47 -0
  274. package/dist/schema/unknown-events.d.ts.map +1 -0
  275. package/dist/schema/unknown-events.js +69 -0
  276. package/dist/schema/unknown-events.js.map +1 -0
  277. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.d.ts +2 -0
  278. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.d.ts.map +1 -0
  279. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js +73 -0
  280. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js.map +1 -0
  281. package/dist/schema-management/common.js +2 -2
  282. package/dist/schema-management/common.js.map +1 -1
  283. package/dist/schema-management/migrations.d.ts +32 -2
  284. package/dist/schema-management/migrations.d.ts.map +1 -1
  285. package/dist/schema-management/migrations.js +38 -6
  286. package/dist/schema-management/migrations.js.map +1 -1
  287. package/dist/schema-management/validate-schema.d.ts +3 -3
  288. package/dist/schema-management/validate-schema.d.ts.map +1 -1
  289. package/dist/schema-management/validate-schema.js +2 -2
  290. package/dist/schema-management/validate-schema.js.map +1 -1
  291. package/dist/sql-queries/sql-queries.d.ts.map +1 -1
  292. package/dist/sql-queries/sql-queries.js +18 -6
  293. package/dist/sql-queries/sql-queries.js.map +1 -1
  294. package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
  295. package/dist/sql-queries/sql-query-builder.js.map +1 -1
  296. package/dist/sqlite-db-helper.js +3 -3
  297. package/dist/sqlite-db-helper.js.map +1 -1
  298. package/dist/sqlite-types.d.ts +5 -5
  299. package/dist/sqlite-types.d.ts.map +1 -1
  300. package/dist/sqlite-types.js.map +1 -1
  301. package/dist/sync/ClientSessionSyncProcessor.d.ts +12 -12
  302. package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
  303. package/dist/sync/ClientSessionSyncProcessor.js +99 -114
  304. package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
  305. package/dist/sync/errors.d.ts +0 -33
  306. package/dist/sync/errors.d.ts.map +1 -1
  307. package/dist/sync/errors.js +5 -22
  308. package/dist/sync/errors.js.map +1 -1
  309. package/dist/sync/index.d.ts +2 -0
  310. package/dist/sync/index.d.ts.map +1 -1
  311. package/dist/sync/index.js +2 -0
  312. package/dist/sync/index.js.map +1 -1
  313. package/dist/sync/mock-sync-backend.d.ts +10 -8
  314. package/dist/sync/mock-sync-backend.d.ts.map +1 -1
  315. package/dist/sync/mock-sync-backend.js +71 -69
  316. package/dist/sync/mock-sync-backend.js.map +1 -1
  317. package/dist/sync/next/compact-events.d.ts.map +1 -1
  318. package/dist/sync/next/compact-events.js +11 -12
  319. package/dist/sync/next/compact-events.js.map +1 -1
  320. package/dist/sync/next/facts.d.ts +5 -5
  321. package/dist/sync/next/facts.d.ts.map +1 -1
  322. package/dist/sync/next/facts.js +7 -8
  323. package/dist/sync/next/facts.js.map +1 -1
  324. package/dist/sync/next/history-dag-common.d.ts +54 -15
  325. package/dist/sync/next/history-dag-common.d.ts.map +1 -1
  326. package/dist/sync/next/history-dag-common.js +198 -9
  327. package/dist/sync/next/history-dag-common.js.map +1 -1
  328. package/dist/sync/next/history-dag.d.ts.map +1 -1
  329. package/dist/sync/next/history-dag.js +11 -11
  330. package/dist/sync/next/history-dag.js.map +1 -1
  331. package/dist/sync/next/rebase-events.d.ts +5 -5
  332. package/dist/sync/next/rebase-events.d.ts.map +1 -1
  333. package/dist/sync/next/rebase-events.js +6 -6
  334. package/dist/sync/next/rebase-events.js.map +1 -1
  335. package/dist/sync/next/test/compact-events.calculator.test.js +2 -2
  336. package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
  337. package/dist/sync/next/test/compact-events.test.d.ts.map +1 -1
  338. package/dist/sync/next/test/compact-events.test.js +2 -2
  339. package/dist/sync/next/test/compact-events.test.js.map +1 -1
  340. package/dist/sync/next/test/event-fixtures.d.ts +2 -2
  341. package/dist/sync/next/test/event-fixtures.d.ts.map +1 -1
  342. package/dist/sync/next/test/event-fixtures.js +11 -11
  343. package/dist/sync/next/test/event-fixtures.js.map +1 -1
  344. package/dist/sync/sync-backend-kv.d.ts +3 -3
  345. package/dist/sync/sync-backend-kv.d.ts.map +1 -1
  346. package/dist/sync/sync-backend-kv.js +3 -3
  347. package/dist/sync/sync-backend-kv.js.map +1 -1
  348. package/dist/sync/sync-backend.d.ts +33 -13
  349. package/dist/sync/sync-backend.d.ts.map +1 -1
  350. package/dist/sync/sync-backend.js +38 -1
  351. package/dist/sync/sync-backend.js.map +1 -1
  352. package/dist/sync/sync.d.ts +23 -2
  353. package/dist/sync/sync.d.ts.map +1 -1
  354. package/dist/sync/syncstate.d.ts +55 -55
  355. package/dist/sync/syncstate.d.ts.map +1 -1
  356. package/dist/sync/syncstate.js +80 -98
  357. package/dist/sync/syncstate.js.map +1 -1
  358. package/dist/sync/syncstate.test.js +221 -132
  359. package/dist/sync/syncstate.test.js.map +1 -1
  360. package/dist/sync/transport-chunking.d.ts +36 -0
  361. package/dist/sync/transport-chunking.d.ts.map +1 -0
  362. package/dist/sync/transport-chunking.js +56 -0
  363. package/dist/sync/transport-chunking.js.map +1 -0
  364. package/dist/sync/validate-push-payload.d.ts +2 -2
  365. package/dist/sync/validate-push-payload.d.ts.map +1 -1
  366. package/dist/sync/validate-push-payload.js +4 -6
  367. package/dist/sync/validate-push-payload.js.map +1 -1
  368. package/dist/testing/event-factory.d.ts +68 -0
  369. package/dist/testing/event-factory.d.ts.map +1 -0
  370. package/dist/testing/event-factory.js +78 -0
  371. package/dist/testing/event-factory.js.map +1 -0
  372. package/dist/testing/mod.d.ts +2 -0
  373. package/dist/testing/mod.d.ts.map +1 -0
  374. package/dist/testing/mod.js +2 -0
  375. package/dist/testing/mod.js.map +1 -0
  376. package/dist/util.js +2 -2
  377. package/dist/util.js.map +1 -1
  378. package/dist/version.d.ts +24 -5
  379. package/dist/version.d.ts.map +1 -1
  380. package/dist/version.js +25 -8
  381. package/dist/version.js.map +1 -1
  382. package/package.json +69 -16
  383. package/src/ClientSessionLeaderThreadProxy.ts +27 -12
  384. package/src/WorkerTransportError.ts +12 -0
  385. package/src/adapter-types.ts +50 -7
  386. package/src/bounded-collections.ts +6 -5
  387. package/src/debug-info.ts +37 -6
  388. package/src/devtools/devtools-compatibility.test.ts +18 -0
  389. package/src/devtools/devtools-messages-client-session.ts +22 -4
  390. package/src/devtools/devtools-messages-common.ts +7 -12
  391. package/src/devtools/devtools-messages-leader.ts +29 -10
  392. package/src/devtools/devtools-sessioninfo.ts +8 -5
  393. package/src/devtools/mod.ts +11 -2
  394. package/src/errors.ts +32 -24
  395. package/src/index.ts +4 -1
  396. package/src/leader-thread/LeaderSyncProcessor.ts +523 -373
  397. package/src/leader-thread/RejectedPushError.ts +106 -0
  398. package/src/leader-thread/connection.ts +1 -1
  399. package/src/leader-thread/eventlog.ts +112 -39
  400. package/src/leader-thread/leader-worker-devtools.ts +201 -120
  401. package/src/leader-thread/make-leader-thread-layer.test.ts +44 -0
  402. package/src/leader-thread/make-leader-thread-layer.ts +125 -40
  403. package/src/leader-thread/materialize-event.ts +40 -10
  404. package/src/leader-thread/mod.ts +1 -0
  405. package/src/leader-thread/recreate-db.ts +7 -7
  406. package/src/leader-thread/shutdown-channel.ts +4 -8
  407. package/src/leader-thread/stream-events.ts +206 -0
  408. package/src/leader-thread/types.ts +68 -18
  409. package/src/logging.ts +62 -0
  410. package/src/make-client-session.ts +11 -5
  411. package/src/materializer-helper.ts +27 -16
  412. package/src/otel.ts +13 -2
  413. package/src/rematerialize-from-eventlog.ts +61 -51
  414. package/src/schema/EventDef/define.ts +217 -0
  415. package/src/schema/EventDef/deprecated.test.ts +129 -0
  416. package/src/schema/EventDef/deprecated.ts +175 -0
  417. package/src/schema/EventDef/event-def.ts +125 -0
  418. package/src/schema/EventDef/facts.ts +135 -0
  419. package/src/schema/EventDef/materializer.ts +172 -0
  420. package/src/schema/EventDef/mod.ts +5 -0
  421. package/src/schema/EventSequenceNumber/client.ts +257 -0
  422. package/src/schema/EventSequenceNumber/global.ts +19 -0
  423. package/src/schema/EventSequenceNumber/mod.ts +37 -0
  424. package/src/schema/EventSequenceNumber.test.ts +72 -53
  425. package/src/schema/LiveStoreEvent/client.test.ts +129 -0
  426. package/src/schema/LiveStoreEvent/client.ts +235 -0
  427. package/src/schema/LiveStoreEvent/for-event-def.ts +60 -0
  428. package/src/schema/LiveStoreEvent/global.ts +45 -0
  429. package/src/schema/LiveStoreEvent/input.ts +63 -0
  430. package/src/schema/LiveStoreEvent/mod.ts +4 -0
  431. package/src/schema/events.ts +1 -1
  432. package/src/schema/mod.ts +6 -4
  433. package/src/schema/schema.ts +46 -5
  434. package/src/schema/state/sqlite/client-document-def.test.ts +144 -5
  435. package/src/schema/state/sqlite/client-document-def.ts +47 -34
  436. package/src/schema/state/sqlite/column-annotations.test.ts +3 -2
  437. package/src/schema/state/sqlite/column-annotations.ts +2 -1
  438. package/src/schema/state/sqlite/column-def.test.ts +66 -12
  439. package/src/schema/state/sqlite/column-def.ts +119 -47
  440. package/src/schema/state/sqlite/column-spec.test.ts +32 -17
  441. package/src/schema/state/sqlite/column-spec.ts +37 -11
  442. package/src/schema/state/sqlite/db-schema/ast/sqlite.ts +2 -2
  443. package/src/schema/state/sqlite/db-schema/dsl/field-defs.test.ts +2 -1
  444. package/src/schema/state/sqlite/db-schema/dsl/field-defs.ts +41 -15
  445. package/src/schema/state/sqlite/db-schema/dsl/mod.ts +13 -19
  446. package/src/schema/state/sqlite/mod.ts +7 -8
  447. package/src/schema/state/sqlite/query-builder/api.ts +55 -17
  448. package/src/schema/state/sqlite/query-builder/astToSql.ts +110 -21
  449. package/src/schema/state/sqlite/query-builder/impl.test.ts +267 -93
  450. package/src/schema/state/sqlite/query-builder/impl.ts +26 -13
  451. package/src/schema/state/sqlite/schema-helpers.test.ts +44 -0
  452. package/src/schema/state/sqlite/schema-helpers.ts +30 -22
  453. package/src/schema/state/sqlite/system-tables/eventlog-tables.ts +64 -0
  454. package/src/schema/state/sqlite/system-tables/mod.ts +2 -0
  455. package/src/schema/state/sqlite/system-tables/state-tables.ts +69 -0
  456. package/src/schema/state/sqlite/table-def.test.ts +114 -3
  457. package/src/schema/state/sqlite/table-def.ts +16 -22
  458. package/src/schema/unknown-events.ts +131 -0
  459. package/src/schema-management/__tests__/migrations-autoincrement-quoting.test.ts +88 -0
  460. package/src/schema-management/common.ts +2 -2
  461. package/src/schema-management/migrations.ts +42 -9
  462. package/src/schema-management/validate-schema.ts +3 -3
  463. package/src/sql-queries/sql-queries.ts +18 -6
  464. package/src/sql-queries/sql-query-builder.ts +1 -0
  465. package/src/sqlite-db-helper.ts +3 -3
  466. package/src/sqlite-types.ts +6 -5
  467. package/src/sync/ClientSessionSyncProcessor.ts +152 -142
  468. package/src/sync/errors.ts +12 -24
  469. package/src/sync/index.ts +2 -0
  470. package/src/sync/mock-sync-backend.ts +146 -104
  471. package/src/sync/next/compact-events.ts +10 -11
  472. package/src/sync/next/facts.ts +13 -14
  473. package/src/sync/next/history-dag-common.ts +280 -26
  474. package/src/sync/next/history-dag.ts +17 -13
  475. package/src/sync/next/rebase-events.ts +12 -12
  476. package/src/sync/next/test/compact-events.calculator.test.ts +3 -2
  477. package/src/sync/next/test/compact-events.test.ts +4 -3
  478. package/src/sync/next/test/event-fixtures.ts +13 -13
  479. package/src/sync/sync-backend-kv.ts +4 -3
  480. package/src/sync/sync-backend.ts +66 -17
  481. package/src/sync/sync.ts +24 -2
  482. package/src/sync/syncstate.test.ts +583 -419
  483. package/src/sync/syncstate.ts +127 -122
  484. package/src/sync/transport-chunking.ts +90 -0
  485. package/src/sync/validate-push-payload.ts +6 -8
  486. package/src/testing/event-factory.ts +131 -0
  487. package/src/testing/mod.ts +1 -0
  488. package/src/util.ts +2 -2
  489. package/src/version.ts +33 -8
  490. package/dist/schema/EventDef.d.ts +0 -126
  491. package/dist/schema/EventDef.d.ts.map +0 -1
  492. package/dist/schema/EventDef.js +0 -46
  493. package/dist/schema/EventDef.js.map +0 -1
  494. package/dist/schema/EventSequenceNumber.d.ts +0 -80
  495. package/dist/schema/EventSequenceNumber.d.ts.map +0 -1
  496. package/dist/schema/EventSequenceNumber.js +0 -139
  497. package/dist/schema/EventSequenceNumber.js.map +0 -1
  498. package/dist/schema/LiveStoreEvent.d.ts.map +0 -1
  499. package/dist/schema/LiveStoreEvent.js +0 -147
  500. package/dist/schema/LiveStoreEvent.js.map +0 -1
  501. package/dist/schema/state/sqlite/system-tables.d.ts.map +0 -1
  502. package/dist/schema/state/sqlite/system-tables.js +0 -81
  503. package/dist/schema/state/sqlite/system-tables.js.map +0 -1
  504. package/dist/sync/next/graphology.d.ts +0 -8
  505. package/dist/sync/next/graphology.d.ts.map +0 -1
  506. package/dist/sync/next/graphology.js +0 -30
  507. package/dist/sync/next/graphology.js.map +0 -1
  508. package/dist/sync/next/graphology_.d.ts +0 -3
  509. package/dist/sync/next/graphology_.d.ts.map +0 -1
  510. package/dist/sync/next/graphology_.js +0 -3
  511. package/dist/sync/next/graphology_.js.map +0 -1
  512. package/src/schema/EventDef.ts +0 -222
  513. package/src/schema/EventSequenceNumber.ts +0 -199
  514. package/src/schema/LiveStoreEvent.ts +0 -286
  515. package/src/schema/state/sqlite/system-tables.ts +0 -106
  516. package/src/sync/next/ambient.d.ts +0 -3
  517. package/src/sync/next/graphology.ts +0 -41
  518. package/src/sync/next/graphology_.ts +0 -2
@@ -1,14 +1,17 @@
1
1
  import { memoizeByRef } from '@livestore/utils'
2
2
  import { Chunk, Effect, Option, Schema, Stream } from '@livestore/utils/effect'
3
3
 
4
- import { type SqliteDb, UnexpectedError } from './adapter-types.ts'
4
+ import { type SqliteDb, UnknownError } from './adapter-types.ts'
5
5
  import type { MaterializeEvent } from './leader-thread/mod.ts'
6
6
  import type { EventDef, LiveStoreSchema } from './schema/mod.ts'
7
- import { EventSequenceNumber, getEventDef, LiveStoreEvent, SystemTables } from './schema/mod.ts'
7
+ import { EventSequenceNumber, LiveStoreEvent, resolveEventDef, SystemTables } from './schema/mod.ts'
8
8
  import type { PreparedBindValues } from './util.ts'
9
9
  import { sql } from './util.ts'
10
10
 
11
- export const rematerializeFromEventlog = ({
11
+ /** Parse JSON string to unknown value */
12
+ const jsonParse = Schema.decodeUnknownSync(Schema.parseJson())
13
+
14
+ export const rematerializeFromEventlog = Effect.fn('@livestore/common:rematerializeFromEventlog')(function* ({
12
15
  dbEventlog,
13
16
  // TODO re-use this db when bringing back the boot in-memory db implementation
14
17
  // db,
@@ -21,59 +24,69 @@ export const rematerializeFromEventlog = ({
21
24
  schema: LiveStoreSchema
22
25
  onProgress: (_: { done: number; total: number }) => Effect.Effect<void>
23
26
  materializeEvent: MaterializeEvent
24
- }) =>
25
- Effect.gen(function* () {
27
+ }) {
26
28
  const eventsCount = dbEventlog.select<{ count: number }>(
27
29
  `SELECT COUNT(*) AS count FROM ${SystemTables.EVENTLOG_META_TABLE}`,
28
30
  )[0]!.count
29
31
 
30
32
  const hashEventDef = memoizeByRef((event: EventDef.AnyWithoutFn) => Schema.hash(event.schema))
31
33
 
32
- const processEvent = (row: SystemTables.EventlogMetaRow) =>
33
- Effect.gen(function* () {
34
- const eventDef = getEventDef(schema, row.name)
34
+ const processEvent = Effect.fn(`@livestore/common:rematerializeFromEventlog:processEvent`)(function* (
35
+ row: SystemTables.EventlogMetaRow,
36
+ ) {
37
+ const args = jsonParse(row.argsJson)
38
+ const eventEncoded = LiveStoreEvent.Client.EncodedWithMeta.make({
39
+ name: row.name,
40
+ args,
41
+ seqNum: {
42
+ global: row.seqNumGlobal,
43
+ client: row.seqNumClient,
44
+ rebaseGeneration: row.seqNumRebaseGeneration,
45
+ },
46
+ parentSeqNum: {
47
+ global: row.parentSeqNumGlobal,
48
+ client: row.parentSeqNumClient,
49
+ rebaseGeneration: row.parentSeqNumRebaseGeneration,
50
+ },
51
+ clientId: row.clientId,
52
+ sessionId: row.sessionId,
53
+ })
35
54
 
36
- if (hashEventDef(eventDef.eventDef) !== row.schemaHash) {
37
- yield* Effect.logWarning(
38
- `Schema hash mismatch for event definition ${row.name}. Trying to materialize event anyway.`,
39
- )
40
- }
55
+ const resolution = yield* resolveEventDef(schema, {
56
+ operation: '@livestore/common:rematerializeFromEventlog:processEvent',
57
+ event: eventEncoded,
58
+ }).pipe(UnknownError.mapToUnknownError)
41
59
 
42
- const args = JSON.parse(row.argsJson)
60
+ if (resolution._tag === 'unknown') {
61
+ // Old snapshots can contain newer events. Skip until the runtime has
62
+ // been updated; the event stays in the log for future replays.
63
+ return
64
+ }
43
65
 
44
- // Checking whether the schema has changed in an incompatible way
45
- yield* Schema.decodeUnknown(eventDef.eventDef.schema)(args).pipe(
46
- Effect.mapError((cause) =>
47
- UnexpectedError.make({
48
- cause,
49
- note: `\
66
+ const { eventDef } = resolution
67
+
68
+ if (hashEventDef(eventDef) !== row.schemaHash) {
69
+ yield* Effect.logWarning(
70
+ `Schema hash mismatch for event definition ${row.name}. Trying to materialize event anyway.`,
71
+ )
72
+ }
73
+
74
+ // Checking whether the schema has changed in an incompatible way
75
+ yield* Schema.decodeUnknown(eventDef.schema)(args).pipe(
76
+ Effect.mapError((cause) =>
77
+ UnknownError.make({
78
+ cause,
79
+ note: `\
50
80
  There was an error during rematerializing from the eventlog while decoding
51
81
  the persisted event args for event definition "${row.name}".
52
82
  This likely means the schema has changed in an incompatible way.
53
83
  `,
54
- }),
55
- ),
56
- )
84
+ }),
85
+ ),
86
+ )
57
87
 
58
- const eventEncoded = LiveStoreEvent.EncodedWithMeta.make({
59
- seqNum: {
60
- global: row.seqNumGlobal,
61
- client: row.seqNumClient,
62
- rebaseGeneration: row.seqNumRebaseGeneration,
63
- },
64
- parentSeqNum: {
65
- global: row.parentSeqNumGlobal,
66
- client: row.parentSeqNumClient,
67
- rebaseGeneration: row.parentSeqNumRebaseGeneration,
68
- },
69
- name: row.name,
70
- args,
71
- clientId: row.clientId,
72
- sessionId: row.sessionId,
73
- })
74
-
75
- yield* materializeEvent(eventEncoded, { skipEventlog: true })
76
- }).pipe(Effect.withSpan(`@livestore/common:rematerializeFromEventlog:processEvent`))
88
+ yield* materializeEvent(eventEncoded, { skipEventlog: true })
89
+ })
77
90
 
78
91
  const CHUNK_SIZE = 100
79
92
 
@@ -91,21 +104,21 @@ LIMIT ${CHUNK_SIZE}
91
104
  SystemTables.EventlogMetaRow
92
105
  >({ _tag: 'Initial' }, (item) => {
93
106
  // End stream if no more rows
94
- if (Chunk.isChunk(item) && item.length === 0) return Option.none()
107
+ if (Chunk.isChunk(item) === true && item.length === 0) return Option.none()
95
108
 
96
- const lastId = Chunk.isChunk(item)
109
+ const lastId = Chunk.isChunk(item) === true
97
110
  ? Chunk.last(item).pipe(
98
111
  Option.map((_) => ({ global: _.seqNumGlobal, client: _.seqNumClient })),
99
- Option.getOrElse(() => EventSequenceNumber.ROOT),
112
+ Option.getOrElse(() => EventSequenceNumber.Client.ROOT),
100
113
  )
101
- : EventSequenceNumber.ROOT
114
+ : EventSequenceNumber.Client.ROOT
102
115
  const nextItem = Chunk.fromIterable(
103
116
  stmt.select<SystemTables.EventlogMetaRow>({
104
117
  $seqNumGlobal: lastId?.global,
105
118
  $seqNumClient: lastId?.client,
106
119
  } as any as PreparedBindValues),
107
120
  )
108
- const prevItem = Chunk.isChunk(item) ? item : Chunk.empty()
121
+ const prevItem = Chunk.isChunk(item) === true ? item : Chunk.empty()
109
122
  return Option.some([prevItem, nextItem])
110
123
  }).pipe(
111
124
  Stream.bufferChunks({ capacity: 2 }),
@@ -119,7 +132,4 @@ LIMIT ${CHUNK_SIZE}
119
132
  ),
120
133
  Stream.runDrain,
121
134
  )
122
- }).pipe(
123
- Effect.withPerformanceMeasure('@livestore/common:rematerializeFromEventlog'),
124
- Effect.withSpan('@livestore/common:rematerializeFromEventlog'),
125
- )
135
+ }, Effect.withPerformanceMeasure('@livestore/common:rematerializeFromEventlog'))
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Event Definition Functions
3
+ *
4
+ * This module provides functions for creating event definitions in LiveStore.
5
+ * Events are the core unit of state change - all mutations to the database
6
+ * happen through events that are committed to the eventlog.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { Events } from '@livestore/livestore'
11
+ * import { Schema } from 'effect'
12
+ *
13
+ * // Define events for your application
14
+ * export const events = {
15
+ * // Synced events are sent to the sync backend
16
+ * todoCreated: Events.synced({
17
+ * name: 'v1.TodoCreated',
18
+ * schema: Schema.Struct({ id: Schema.String, text: Schema.String }),
19
+ * }),
20
+ *
21
+ * // Client-only events stay local (useful for UI state)
22
+ * uiStateSet: Events.clientOnly({
23
+ * name: 'UiStateSet',
24
+ * schema: Schema.Struct({ selectedId: Schema.NullOr(Schema.String) }),
25
+ * }),
26
+ * }
27
+ * ```
28
+ * @module
29
+ */
30
+
31
+ import { shouldNeverHappen } from '@livestore/utils'
32
+ import { Schema } from '@livestore/utils/effect'
33
+
34
+ import type { EventDef } from './event-def.ts'
35
+ import type { EventDefFactInput, EventDefFacts } from './facts.ts'
36
+
37
+ /** Options for defining an event. */
38
+ export type DefineEventOptions<TTo, TDerived extends boolean = false> = {
39
+ /**
40
+ * Callback defining fact constraints for this event.
41
+ * @experimental This feature is not fully implemented yet.
42
+ */
43
+ facts?: (
44
+ args: TTo,
45
+ currentFacts: EventDefFacts,
46
+ ) => {
47
+ modify?: {
48
+ /** Facts to set (create or update). */
49
+ set?: Iterable<EventDefFactInput>
50
+ /** Facts to unset (remove). */
51
+ unset?: Iterable<EventDefFactInput>
52
+ }
53
+ /**
54
+ * Facts that must exist for this event to be valid.
55
+ * Used for history constraints and compaction rules.
56
+ */
57
+ require?: Iterable<EventDefFactInput>
58
+ }
59
+
60
+ /**
61
+ * When true, the event is only synced within the same client's sessions
62
+ * but never sent to the sync backend. Useful for UI state.
63
+ * @default false
64
+ */
65
+ clientOnly?: boolean
66
+
67
+ /**
68
+ * When true, marks this as a derived event that cannot have materializers.
69
+ * @default false
70
+ */
71
+ derived?: TDerived
72
+
73
+ /**
74
+ * Marks the entire event as deprecated with a reason message.
75
+ * When this event is committed, a warning will be logged.
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * Events.synced({
80
+ * name: 'v1.TodoRenamed',
81
+ * schema: Schema.Struct({ id: Schema.String, name: Schema.String }),
82
+ * deprecated: "Use 'v1.TodoUpdated' instead",
83
+ * })
84
+ * ```
85
+ */
86
+ deprecated?: string
87
+ }
88
+
89
+ /**
90
+ * Creates an event definition with full control over all options.
91
+ *
92
+ * This is the low-level function for creating events. For most cases,
93
+ * prefer using `synced()` or `clientOnly()` which provide simpler APIs.
94
+ *
95
+ * @example
96
+ * ```ts
97
+ * const customEvent = defineEvent({
98
+ * name: 'v1.CustomEvent',
99
+ * schema: Schema.Struct({ data: Schema.String }),
100
+ * clientOnly: false,
101
+ * derived: false,
102
+ * })
103
+ * ```
104
+ */
105
+ export const defineEvent = <TName extends string, TType, TEncoded = TType, TDerived extends boolean = false>(
106
+ args: {
107
+ name: TName
108
+ schema: Schema.Schema<TType, TEncoded>
109
+ } & DefineEventOptions<TType, TDerived>,
110
+ ): EventDef<TName, TType, TEncoded, TDerived> => {
111
+ const { name, schema, ...options } = args
112
+
113
+ const makePartialEvent = (args: TType) => {
114
+ const res = Schema.validateEither(schema)(args)
115
+ if (res._tag === 'Left') {
116
+ shouldNeverHappen(`Invalid event args for event '${name}':`, res.left.message, '\n')
117
+ }
118
+ return { name: name, args }
119
+ }
120
+
121
+ Object.defineProperty(makePartialEvent, 'name', { value: name })
122
+ Object.defineProperty(makePartialEvent, 'schema', { value: schema })
123
+ Object.defineProperty(makePartialEvent, 'encoded', {
124
+ value: (args: TEncoded) => ({ name: name, args }),
125
+ })
126
+
127
+ Object.defineProperty(makePartialEvent, 'options', {
128
+ value: {
129
+ clientOnly: options?.clientOnly ?? false,
130
+ facts: options?.facts !== undefined
131
+ ? (args, currentFacts) => {
132
+ const res = options.facts!(args, currentFacts)
133
+ return {
134
+ modify: {
135
+ set: res.modify?.set !== undefined ? new Set(res.modify.set) : new Set(),
136
+ unset: res.modify?.unset !== undefined ? new Set(res.modify.unset) : new Set(),
137
+ },
138
+ require: res.require !== undefined ? new Set(res.require) : new Set(),
139
+ }
140
+ }
141
+ : undefined,
142
+ derived: options?.derived ?? false,
143
+ deprecated: options?.deprecated,
144
+ } satisfies EventDef.Any['options'],
145
+ })
146
+
147
+ return makePartialEvent as EventDef<TName, TType, TEncoded, TDerived>
148
+ }
149
+
150
+ /**
151
+ * Creates a synced event definition.
152
+ *
153
+ * Synced events are sent to the sync backend and distributed to all connected
154
+ * clients. Use this for collaborative data that should be shared across users
155
+ * and devices.
156
+ *
157
+ * Event names should be versioned (e.g., `v1.TodoCreated`) to support
158
+ * schema evolution over time.
159
+ *
160
+ * @example
161
+ * ```ts
162
+ * import { Events } from '@livestore/livestore'
163
+ * import { Schema } from 'effect'
164
+ *
165
+ * const todoCreated = Events.synced({
166
+ * name: 'v1.TodoCreated',
167
+ * schema: Schema.Struct({
168
+ * id: Schema.String,
169
+ * text: Schema.String,
170
+ * completed: Schema.Boolean,
171
+ * }),
172
+ * })
173
+ *
174
+ * // Commit the event
175
+ * store.commit(todoCreated({ id: 'abc', text: 'Buy milk', completed: false }))
176
+ * ```
177
+ */
178
+ export const synced = <TName extends string, TType, TEncoded = TType>(
179
+ args: {
180
+ name: TName
181
+ schema: Schema.Schema<TType, TEncoded>
182
+ } & Omit<DefineEventOptions<TType>, 'derived' | 'clientOnly'>,
183
+ ): EventDef<TName, TType, TEncoded> => defineEvent({ ...args, clientOnly: false })
184
+
185
+ /**
186
+ * Creates a client-only event definition.
187
+ *
188
+ * Client-only events are synced within the same client's sessions (e.g., across
189
+ * browser tabs) but are never sent to the sync backend. Use this for local UI
190
+ * state like selected items, filter settings, or draft content.
191
+ *
192
+ * Note: Client-only events still require materializers and are stored in the
193
+ * local eventlog, they just don't participate in server-side sync.
194
+ *
195
+ * @example
196
+ * ```ts
197
+ * import { Events } from '@livestore/livestore'
198
+ * import { Schema } from 'effect'
199
+ *
200
+ * const uiStateSet = Events.clientOnly({
201
+ * name: 'UiStateSet',
202
+ * schema: Schema.Struct({
203
+ * selectedTodoId: Schema.NullOr(Schema.String),
204
+ * filterMode: Schema.Literal('all', 'active', 'completed'),
205
+ * }),
206
+ * })
207
+ *
208
+ * // Update local UI state
209
+ * store.commit(uiStateSet({ selectedTodoId: 'abc', filterMode: 'active' }))
210
+ * ```
211
+ */
212
+ export const clientOnly = <TName extends string, TType, TEncoded = TType>(
213
+ args: {
214
+ name: TName
215
+ schema: Schema.Schema<TType, TEncoded>
216
+ } & Omit<DefineEventOptions<TType>, 'derived' | 'clientOnly'>,
217
+ ): EventDef<TName, TType, TEncoded> => defineEvent({ ...args, clientOnly: true })
@@ -0,0 +1,129 @@
1
+ import { afterEach, beforeEach, describe, expect, test } from 'vitest'
2
+
3
+ import { Effect, Logger, Schema } from '@livestore/utils/effect'
4
+
5
+ import { synced } from './define.ts'
6
+ import {
7
+ deprecated,
8
+ findDeprecatedFieldsWithValues,
9
+ getDeprecatedReason,
10
+ isDeprecated,
11
+ logDeprecationWarnings,
12
+ resetDeprecationWarnings,
13
+ } from './deprecated.ts'
14
+
15
+ describe('deprecated annotations', () => {
16
+ test('adds deprecation annotation to schema', () => {
17
+ const schema = Schema.String.pipe(deprecated('Use newField instead'))
18
+ expect(isDeprecated(schema)).toBe(true)
19
+ expect(getDeprecatedReason(schema)._tag).toBe('Some')
20
+ })
21
+
22
+ test('works with optional fields in Struct', () => {
23
+ const struct = Schema.Struct({
24
+ oldField: Schema.optional(Schema.String).pipe(deprecated('Legacy')),
25
+ })
26
+ expect(findDeprecatedFieldsWithValues(struct, { oldField: 'x' })).toEqual([{ field: 'oldField', reason: 'Legacy' }])
27
+ })
28
+
29
+ test('non-deprecated schemas return false', () => {
30
+ expect(isDeprecated(Schema.String)).toBe(false)
31
+ })
32
+
33
+ test('ignores deprecated fields without values', () => {
34
+ const schema = Schema.Struct({
35
+ id: Schema.String,
36
+ old: Schema.optional(Schema.String).pipe(deprecated('x')),
37
+ })
38
+ expect(findDeprecatedFieldsWithValues(schema, { id: '1' })).toEqual([])
39
+ })
40
+
41
+ test('finds multiple deprecated fields', () => {
42
+ const schema = Schema.Struct({
43
+ a: Schema.optional(Schema.String).pipe(deprecated('A')),
44
+ b: Schema.optional(Schema.String).pipe(deprecated('B')),
45
+ })
46
+ const result = findDeprecatedFieldsWithValues(schema, { a: '1', b: '2' })
47
+ expect(result).toHaveLength(2)
48
+ })
49
+ })
50
+
51
+ describe('logDeprecationWarnings', () => {
52
+ let logs: unknown[][]
53
+
54
+ beforeEach(() => {
55
+ resetDeprecationWarnings()
56
+ logs = []
57
+ })
58
+
59
+ afterEach(() => resetDeprecationWarnings())
60
+
61
+ const run = (effect: Effect.Effect<void>) =>
62
+ Effect.runSync(
63
+ effect.pipe(
64
+ Effect.provide(
65
+ Logger.replace(
66
+ Logger.defaultLogger,
67
+ Logger.make(({ message }) => logs.push(message as unknown[])),
68
+ ),
69
+ ),
70
+ ),
71
+ )
72
+
73
+ test('logs event deprecation warning', () => {
74
+ const event = synced({ name: 'Old', schema: Schema.Struct({ id: Schema.String }), deprecated: 'Use New' })
75
+ run(logDeprecationWarnings(event, { id: '1' }))
76
+ expect(logs).toEqual([['@livestore/schema:deprecated-event', { event: 'Old', reason: 'Use New' }]])
77
+ })
78
+
79
+ test('logs field deprecation warning', () => {
80
+ const event = synced({
81
+ name: 'Ev',
82
+ schema: Schema.Struct({ old: Schema.optional(Schema.String).pipe(deprecated('Use new')) }),
83
+ })
84
+ run(logDeprecationWarnings(event, { old: 'x' }))
85
+ expect(logs).toEqual([['@livestore/schema:deprecated-field', { event: 'Ev', field: 'old', reason: 'Use new' }]])
86
+ })
87
+
88
+ test('deduplicates event warnings', () => {
89
+ const event = synced({ name: 'Dup', schema: Schema.Struct({ id: Schema.String }), deprecated: 'x' })
90
+ run(logDeprecationWarnings(event, { id: '1' }))
91
+ run(logDeprecationWarnings(event, { id: '2' }))
92
+ expect(logs).toHaveLength(1)
93
+ })
94
+
95
+ test('deduplicates field warnings', () => {
96
+ const event = synced({
97
+ name: 'DupField',
98
+ schema: Schema.Struct({ old: Schema.optional(Schema.String).pipe(deprecated('x')) }),
99
+ })
100
+ run(logDeprecationWarnings(event, { old: 'a' }))
101
+ run(logDeprecationWarnings(event, { old: 'b' }))
102
+ expect(logs).toHaveLength(1)
103
+ })
104
+
105
+ test('no warning for non-deprecated event', () => {
106
+ const event = synced({ name: 'Normal', schema: Schema.Struct({ id: Schema.String }) })
107
+ run(logDeprecationWarnings(event, { id: '1' }))
108
+ expect(logs).toHaveLength(0)
109
+ })
110
+
111
+ test('no warning when deprecated field is undefined', () => {
112
+ const event = synced({
113
+ name: 'Unused',
114
+ schema: Schema.Struct({ old: Schema.optional(Schema.String).pipe(deprecated('x')) }),
115
+ })
116
+ run(logDeprecationWarnings(event, {}))
117
+ expect(logs).toHaveLength(0)
118
+ })
119
+
120
+ test('logs both event and field warnings', () => {
121
+ const event = synced({
122
+ name: 'Both',
123
+ schema: Schema.Struct({ old: Schema.optional(Schema.String).pipe(deprecated('F')) }),
124
+ deprecated: 'E',
125
+ })
126
+ run(logDeprecationWarnings(event, { old: 'x' }))
127
+ expect(logs).toHaveLength(2)
128
+ })
129
+ })
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Deprecation Annotations for Events
3
+ *
4
+ * This module provides utilities for marking event fields and entire events as deprecated.
5
+ * When a deprecated field is used or a deprecated event is committed, a warning is logged.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { Events } from '@livestore/livestore'
10
+ * import { Schema } from 'effect'
11
+ * import { deprecated } from '@livestore/common/schema'
12
+ *
13
+ * // Field-level deprecation
14
+ * const todoUpdated = Events.synced({
15
+ * name: 'v1.TodoUpdated',
16
+ * schema: Schema.Struct({
17
+ * id: Schema.String,
18
+ * title: Schema.optional(Schema.String).pipe(deprecated("Use 'text' instead")),
19
+ * text: Schema.optional(Schema.String),
20
+ * }),
21
+ * })
22
+ *
23
+ * // Event-level deprecation
24
+ * const todoRenamed = Events.synced({
25
+ * name: 'v1.TodoRenamed',
26
+ * schema: Schema.Struct({ id: Schema.String, name: Schema.String }),
27
+ * deprecated: "Use 'v1.TodoUpdated' instead",
28
+ * })
29
+ * ```
30
+ * @module
31
+ */
32
+
33
+ import type { Schema } from '@livestore/utils/effect'
34
+ import { Effect, Option, SchemaAST } from '@livestore/utils/effect'
35
+
36
+ import type { EventDef } from './event-def.ts'
37
+
38
+ /** Symbol used to mark schemas as deprecated. */
39
+ export const DeprecatedId = Symbol.for('livestore/schema/annotations/deprecated')
40
+
41
+ /**
42
+ * Marks a schema field as deprecated with a reason message.
43
+ * When an event is committed with a deprecated field that has a value,
44
+ * a warning will be logged.
45
+ *
46
+ * Works with both Schema types and PropertySignatures (from Schema.optional).
47
+ *
48
+ * @param reason - Explanation of why this field is deprecated and what to use instead
49
+ * @returns A function that adds the deprecation annotation to the schema
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * const schema = Schema.Struct({
54
+ * oldField: Schema.optional(Schema.String).pipe(deprecated("Use 'newField' instead")),
55
+ * newField: Schema.optional(Schema.String),
56
+ * })
57
+ * ```
58
+ */
59
+ export const deprecated =
60
+ (reason: string) =>
61
+ <T extends { annotations: (annotations: { readonly [DeprecatedId]?: string }) => T }>(schema: T): T =>
62
+ schema.annotations({ [DeprecatedId]: reason })
63
+
64
+ /**
65
+ * Checks if a schema has a deprecation annotation.
66
+ *
67
+ * @param schema - The schema to check
68
+ * @returns The deprecation reason if deprecated, None otherwise
69
+ */
70
+ export const getDeprecatedReason = <A, I, R>(schema: Schema.Schema<A, I, R>): Option.Option<string> =>
71
+ SchemaAST.getAnnotation<string>(DeprecatedId)(schema.ast)
72
+
73
+ /**
74
+ * Checks if a schema is deprecated.
75
+ *
76
+ * @param schema - The schema to check
77
+ * @returns true if the schema is deprecated
78
+ */
79
+ export const isDeprecated = <A, I, R>(schema: Schema.Schema<A, I, R>): boolean =>
80
+ Option.isSome(getDeprecatedReason(schema))
81
+
82
+ /**
83
+ * Finds deprecated fields with values in the given event arguments.
84
+ * This walks through a Struct schema and checks each property for deprecation.
85
+ *
86
+ * @param schema - The event schema (expected to be a Struct)
87
+ * @param args - The event arguments
88
+ * @returns Array of objects containing field name and deprecation reason
89
+ */
90
+ export const findDeprecatedFieldsWithValues = (
91
+ schema: Schema.Schema.All,
92
+ args: Record<string, unknown>,
93
+ ): Array<{ field: string; reason: string }> => {
94
+ const result: Array<{ field: string; reason: string }> = []
95
+ const ast = schema.ast
96
+
97
+ // Handle TypeLiteral (Struct) schemas
98
+ if (ast._tag === 'TypeLiteral') {
99
+ for (const prop of ast.propertySignatures) {
100
+ const fieldName = String(prop.name)
101
+ const fieldValue = args[fieldName]
102
+
103
+ // Only check fields that have a value (not undefined)
104
+ if (fieldValue !== undefined) {
105
+ // Check deprecation on the property signature itself (for Schema.optional(...).pipe(deprecated(...)))
106
+ const propAnnotations = prop.annotations as Record<symbol, unknown> | undefined
107
+ const deprecationReason = propAnnotations?.[DeprecatedId] as string | undefined
108
+
109
+ // Also check deprecation on the type (for direct field deprecation)
110
+ const typeDeprecation = SchemaAST.getAnnotation<string>(DeprecatedId)(prop.type)
111
+
112
+ const reason = deprecationReason ?? (Option.isSome(typeDeprecation) === true ? typeDeprecation.value : undefined)
113
+ if (reason !== undefined) {
114
+ result.push({ field: fieldName, reason })
115
+ }
116
+ }
117
+ }
118
+ }
119
+
120
+ return result
121
+ }
122
+
123
+ /** Set of event names that have already logged deprecation warnings. */
124
+ const warnedDeprecatedEvents = new Set<string>()
125
+
126
+ /** Map of event+field combinations that have already logged deprecation warnings. */
127
+ const warnedDeprecatedFields = new Set<string>()
128
+
129
+ /**
130
+ * Logs deprecation warnings for an event using Effect.logWarning.
131
+ * Checks both event-level and field-level deprecation, with deduplication.
132
+ *
133
+ * @param eventDef - The event definition to check
134
+ * @param args - The event arguments
135
+ * @returns An Effect that logs warnings for any deprecations found
136
+ */
137
+ export const logDeprecationWarnings = (
138
+ eventDef: EventDef.AnyWithoutFn,
139
+ args: Record<string, unknown>,
140
+ ): Effect.Effect<void> =>
141
+ Effect.gen(function* () {
142
+ const eventName = eventDef.name
143
+
144
+ // Check for event-level deprecation
145
+ const eventDeprecation = eventDef.options.deprecated
146
+ if (eventDeprecation !== undefined && warnedDeprecatedEvents.has(eventName) === false) {
147
+ warnedDeprecatedEvents.add(eventName)
148
+ yield* Effect.logWarning('@livestore/schema:deprecated-event', {
149
+ event: eventName,
150
+ reason: eventDeprecation,
151
+ })
152
+ }
153
+
154
+ // Check for deprecated fields with values
155
+ const deprecatedFields = findDeprecatedFieldsWithValues(eventDef.schema, args)
156
+ for (const { field, reason } of deprecatedFields) {
157
+ const key = `${eventName}:${field}`
158
+ if (warnedDeprecatedFields.has(key) === false) {
159
+ warnedDeprecatedFields.add(key)
160
+ yield* Effect.logWarning('@livestore/schema:deprecated-field', {
161
+ event: eventName,
162
+ field,
163
+ reason,
164
+ })
165
+ }
166
+ }
167
+ })
168
+
169
+ /**
170
+ * Resets the deprecation warning state. Useful for testing.
171
+ */
172
+ export const resetDeprecationWarnings = (): void => {
173
+ warnedDeprecatedEvents.clear()
174
+ warnedDeprecatedFields.clear()
175
+ }