@livestore/common 0.4.0 → 0.5.0-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (421) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/ClientSessionLeaderThreadProxy.d.ts +1 -1
  3. package/dist/ClientSessionLeaderThreadProxy.d.ts.map +1 -1
  4. package/dist/MaterializationJournal.d.ts +44 -0
  5. package/dist/MaterializationJournal.d.ts.map +1 -0
  6. package/dist/MaterializationJournal.js +112 -0
  7. package/dist/MaterializationJournal.js.map +1 -0
  8. package/dist/StateHead.d.ts +26 -0
  9. package/dist/StateHead.d.ts.map +1 -0
  10. package/dist/StateHead.js +50 -0
  11. package/dist/StateHead.js.map +1 -0
  12. package/dist/WorkerTransportError.d.ts +3 -3
  13. package/dist/WorkerTransportError.d.ts.map +1 -1
  14. package/dist/WorkerTransportError.js +3 -3
  15. package/dist/WorkerTransportError.js.map +1 -1
  16. package/dist/__tests__/fixture.d.ts +1 -1
  17. package/dist/__tests__/fixture.d.ts.map +1 -1
  18. package/dist/__tests__/fixture.js +3 -3
  19. package/dist/__tests__/fixture.js.map +1 -1
  20. package/dist/adapter-types.d.ts +29 -57
  21. package/dist/adapter-types.d.ts.map +1 -1
  22. package/dist/adapter-types.js +20 -37
  23. package/dist/adapter-types.js.map +1 -1
  24. package/dist/debug-info.d.ts +56 -56
  25. package/dist/debug-info.d.ts.map +1 -1
  26. package/dist/debug-info.js +28 -41
  27. package/dist/debug-info.js.map +1 -1
  28. package/dist/defs.d.ts +9 -9
  29. package/dist/defs.js +2 -2
  30. package/dist/devtools/devtools-compatibility.test.js +1 -0
  31. package/dist/devtools/devtools-compatibility.test.js.map +1 -1
  32. package/dist/devtools/devtools-messages-client-session.d.ts +520 -332
  33. package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -1
  34. package/dist/devtools/devtools-messages-client-session.js +76 -74
  35. package/dist/devtools/devtools-messages-client-session.js.map +1 -1
  36. package/dist/devtools/devtools-messages-common.d.ts +27 -27
  37. package/dist/devtools/devtools-messages-common.d.ts.map +1 -1
  38. package/dist/devtools/devtools-messages-common.js +5 -5
  39. package/dist/devtools/devtools-messages-common.js.map +1 -1
  40. package/dist/devtools/devtools-messages-leader.d.ts +405 -343
  41. package/dist/devtools/devtools-messages-leader.d.ts.map +1 -1
  42. package/dist/devtools/devtools-messages-leader.js +101 -89
  43. package/dist/devtools/devtools-messages-leader.js.map +1 -1
  44. package/dist/devtools/devtools-sessioninfo.d.ts +18 -19
  45. package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -1
  46. package/dist/devtools/devtools-sessioninfo.js +8 -5
  47. package/dist/devtools/devtools-sessioninfo.js.map +1 -1
  48. package/dist/devtools/mod.d.ts +4 -5
  49. package/dist/devtools/mod.d.ts.map +1 -1
  50. package/dist/devtools/mod.js +9 -5
  51. package/dist/devtools/mod.js.map +1 -1
  52. package/dist/errors.d.ts +45 -69
  53. package/dist/errors.d.ts.map +1 -1
  54. package/dist/errors.js +18 -16
  55. package/dist/errors.js.map +1 -1
  56. package/dist/index.d.ts +4 -1
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +4 -1
  59. package/dist/index.js.map +1 -1
  60. package/dist/leader-thread/LeaderSyncProcessor.d.ts +66 -18
  61. package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
  62. package/dist/leader-thread/LeaderSyncProcessor.js +519 -461
  63. package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
  64. package/dist/leader-thread/RejectedPushError.d.ts +67 -36
  65. package/dist/leader-thread/RejectedPushError.d.ts.map +1 -1
  66. package/dist/leader-thread/RejectedPushError.js +24 -5
  67. package/dist/leader-thread/RejectedPushError.js.map +1 -1
  68. package/dist/leader-thread/connection.d.ts +1 -0
  69. package/dist/leader-thread/connection.d.ts.map +1 -1
  70. package/dist/leader-thread/connection.js +9 -8
  71. package/dist/leader-thread/connection.js.map +1 -1
  72. package/dist/leader-thread/eventlog.d.ts +4 -4
  73. package/dist/leader-thread/eventlog.d.ts.map +1 -1
  74. package/dist/leader-thread/eventlog.js +6 -6
  75. package/dist/leader-thread/eventlog.js.map +1 -1
  76. package/dist/leader-thread/leader-worker-devtools.d.ts +1 -1
  77. package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
  78. package/dist/leader-thread/leader-worker-devtools.js +33 -17
  79. package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
  80. package/dist/leader-thread/make-leader-thread-layer.d.ts +9 -5
  81. package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
  82. package/dist/leader-thread/make-leader-thread-layer.js +25 -35
  83. package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
  84. package/dist/leader-thread/make-leader-thread-layer.test.js +7 -7
  85. package/dist/leader-thread/make-leader-thread-layer.test.js.map +1 -1
  86. package/dist/leader-thread/materialize-event.d.ts +2 -1
  87. package/dist/leader-thread/materialize-event.d.ts.map +1 -1
  88. package/dist/leader-thread/materialize-event.js +4 -0
  89. package/dist/leader-thread/materialize-event.js.map +1 -1
  90. package/dist/leader-thread/recreate-db.d.ts.map +1 -1
  91. package/dist/leader-thread/recreate-db.js +18 -39
  92. package/dist/leader-thread/recreate-db.js.map +1 -1
  93. package/dist/leader-thread/shutdown-channel.d.ts +2 -6
  94. package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
  95. package/dist/leader-thread/shutdown-channel.js +2 -3
  96. package/dist/leader-thread/shutdown-channel.js.map +1 -1
  97. package/dist/leader-thread/stream-events.d.ts +4 -7
  98. package/dist/leader-thread/stream-events.d.ts.map +1 -1
  99. package/dist/leader-thread/stream-events.js +13 -16
  100. package/dist/leader-thread/stream-events.js.map +1 -1
  101. package/dist/leader-thread/types.d.ts +32 -69
  102. package/dist/leader-thread/types.d.ts.map +1 -1
  103. package/dist/leader-thread/types.js +5 -5
  104. package/dist/leader-thread/types.js.map +1 -1
  105. package/dist/logging.d.ts +5 -30
  106. package/dist/logging.d.ts.map +1 -1
  107. package/dist/logging.js +1 -32
  108. package/dist/logging.js.map +1 -1
  109. package/dist/make-client-session.d.ts +1 -2
  110. package/dist/make-client-session.d.ts.map +1 -1
  111. package/dist/make-client-session.js +3 -3
  112. package/dist/make-client-session.js.map +1 -1
  113. package/dist/materializer-helper.d.ts +0 -1
  114. package/dist/materializer-helper.d.ts.map +1 -1
  115. package/dist/materializer-helper.js +7 -35
  116. package/dist/materializer-helper.js.map +1 -1
  117. package/dist/otel.d.ts +2 -3
  118. package/dist/otel.d.ts.map +1 -1
  119. package/dist/otel.js +2 -7
  120. package/dist/otel.js.map +1 -1
  121. package/dist/rematerialize-from-eventlog.d.ts.map +1 -1
  122. package/dist/rematerialize-from-eventlog.js +28 -26
  123. package/dist/rematerialize-from-eventlog.js.map +1 -1
  124. package/dist/schema/EventDef/define.d.ts +4 -4
  125. package/dist/schema/EventDef/define.d.ts.map +1 -1
  126. package/dist/schema/EventDef/define.js +5 -5
  127. package/dist/schema/EventDef/define.js.map +1 -1
  128. package/dist/schema/EventDef/define.test.d.ts +2 -0
  129. package/dist/schema/EventDef/define.test.d.ts.map +1 -0
  130. package/dist/schema/EventDef/define.test.js +23 -0
  131. package/dist/schema/EventDef/define.test.js.map +1 -0
  132. package/dist/schema/EventDef/deprecated.d.ts +8 -13
  133. package/dist/schema/EventDef/deprecated.d.ts.map +1 -1
  134. package/dist/schema/EventDef/deprecated.js +12 -13
  135. package/dist/schema/EventDef/deprecated.js.map +1 -1
  136. package/dist/schema/EventDef/deprecated.test.js +1 -1
  137. package/dist/schema/EventDef/deprecated.test.js.map +1 -1
  138. package/dist/schema/EventDef/event-def.d.ts +1 -1
  139. package/dist/schema/EventDef/event-def.d.ts.map +1 -1
  140. package/dist/schema/EventSequenceNumber/client.d.ts +12 -12
  141. package/dist/schema/EventSequenceNumber/client.d.ts.map +1 -1
  142. package/dist/schema/EventSequenceNumber/client.js +8 -9
  143. package/dist/schema/EventSequenceNumber/client.js.map +1 -1
  144. package/dist/schema/EventSequenceNumber/global.d.ts +2 -2
  145. package/dist/schema/EventSequenceNumber/global.d.ts.map +1 -1
  146. package/dist/schema/EventSequenceNumber/global.js +1 -1
  147. package/dist/schema/EventSequenceNumber/global.js.map +1 -1
  148. package/dist/schema/EventSequenceNumber.test.js +5 -5
  149. package/dist/schema/EventSequenceNumber.test.js.map +1 -1
  150. package/dist/schema/LiveStoreEvent/client.d.ts +50 -179
  151. package/dist/schema/LiveStoreEvent/client.d.ts.map +1 -1
  152. package/dist/schema/LiveStoreEvent/client.js +32 -29
  153. package/dist/schema/LiveStoreEvent/client.js.map +1 -1
  154. package/dist/schema/LiveStoreEvent/client.test.js +11 -2
  155. package/dist/schema/LiveStoreEvent/client.test.js.map +1 -1
  156. package/dist/schema/LiveStoreEvent/for-event-def.d.ts +7 -7
  157. package/dist/schema/LiveStoreEvent/for-event-def.d.ts.map +1 -1
  158. package/dist/schema/LiveStoreEvent/global.d.ts +6 -6
  159. package/dist/schema/LiveStoreEvent/global.d.ts.map +1 -1
  160. package/dist/schema/LiveStoreEvent/global.js +1 -1
  161. package/dist/schema/LiveStoreEvent/global.js.map +1 -1
  162. package/dist/schema/LiveStoreEvent/input.d.ts +5 -5
  163. package/dist/schema/LiveStoreEvent/input.d.ts.map +1 -1
  164. package/dist/schema/LiveStoreEvent/input.js +3 -3
  165. package/dist/schema/LiveStoreEvent/input.js.map +1 -1
  166. package/dist/schema/mod.d.ts +1 -0
  167. package/dist/schema/mod.d.ts.map +1 -1
  168. package/dist/schema/mod.js +1 -0
  169. package/dist/schema/mod.js.map +1 -1
  170. package/dist/schema/schema.d.ts.map +1 -1
  171. package/dist/schema/schema.js +3 -2
  172. package/dist/schema/schema.js.map +1 -1
  173. package/dist/schema/state/sqlite/client-document-def.d.ts +12 -17
  174. package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -1
  175. package/dist/schema/state/sqlite/client-document-def.js +23 -20
  176. package/dist/schema/state/sqlite/client-document-def.js.map +1 -1
  177. package/dist/schema/state/sqlite/client-document-def.test.js +29 -8
  178. package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -1
  179. package/dist/schema/state/sqlite/column-annotations.d.ts +13 -13
  180. package/dist/schema/state/sqlite/column-annotations.d.ts.map +1 -1
  181. package/dist/schema/state/sqlite/column-annotations.js +13 -15
  182. package/dist/schema/state/sqlite/column-annotations.js.map +1 -1
  183. package/dist/schema/state/sqlite/column-annotations.test.js +19 -43
  184. package/dist/schema/state/sqlite/column-annotations.test.js.map +1 -1
  185. package/dist/schema/state/sqlite/column-def.d.ts +1 -1
  186. package/dist/schema/state/sqlite/column-def.d.ts.map +1 -1
  187. package/dist/schema/state/sqlite/column-def.js +57 -31
  188. package/dist/schema/state/sqlite/column-def.js.map +1 -1
  189. package/dist/schema/state/sqlite/column-def.test.js +118 -72
  190. package/dist/schema/state/sqlite/column-def.test.js.map +1 -1
  191. package/dist/schema/state/sqlite/column-spec.js.map +1 -1
  192. package/dist/schema/state/sqlite/column-spec.test.js +2 -2
  193. package/dist/schema/state/sqlite/db-schema/ast/sqlite.d.ts +2 -2
  194. package/dist/schema/state/sqlite/db-schema/ast/sqlite.d.ts.map +1 -1
  195. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js +13 -4
  196. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js.map +1 -1
  197. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts +9 -9
  198. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts.map +1 -1
  199. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js +8 -13
  200. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js.map +1 -1
  201. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js +27 -16
  202. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js.map +1 -1
  203. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts +13 -11
  204. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts.map +1 -1
  205. package/dist/schema/state/sqlite/db-schema/dsl/mod.js +5 -3
  206. package/dist/schema/state/sqlite/db-schema/dsl/mod.js.map +1 -1
  207. package/dist/schema/state/sqlite/mod.d.ts +1 -3
  208. package/dist/schema/state/sqlite/mod.d.ts.map +1 -1
  209. package/dist/schema/state/sqlite/mod.js +1 -1
  210. package/dist/schema/state/sqlite/mod.js.map +1 -1
  211. package/dist/schema/state/sqlite/persistence.d.ts +11 -0
  212. package/dist/schema/state/sqlite/persistence.d.ts.map +1 -0
  213. package/dist/schema/state/sqlite/persistence.js +10 -0
  214. package/dist/schema/state/sqlite/persistence.js.map +1 -0
  215. package/dist/schema/state/sqlite/query-builder/api.d.ts +7 -7
  216. package/dist/schema/state/sqlite/query-builder/api.d.ts.map +1 -1
  217. package/dist/schema/state/sqlite/query-builder/astToSql.d.ts.map +1 -1
  218. package/dist/schema/state/sqlite/query-builder/astToSql.js +27 -23
  219. package/dist/schema/state/sqlite/query-builder/astToSql.js.map +1 -1
  220. package/dist/schema/state/sqlite/query-builder/impl.d.ts +3 -1
  221. package/dist/schema/state/sqlite/query-builder/impl.d.ts.map +1 -1
  222. package/dist/schema/state/sqlite/query-builder/impl.js +16 -14
  223. package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -1
  224. package/dist/schema/state/sqlite/query-builder/impl.test.js +362 -596
  225. package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -1
  226. package/dist/schema/state/sqlite/schema-helpers.js +1 -1
  227. package/dist/schema/state/sqlite/schema-helpers.js.map +1 -1
  228. package/dist/schema/state/sqlite/system-tables/eventlog-tables.d.ts +102 -134
  229. package/dist/schema/state/sqlite/system-tables/eventlog-tables.d.ts.map +1 -1
  230. package/dist/schema/state/sqlite/system-tables/eventlog-tables.js +2 -2
  231. package/dist/schema/state/sqlite/system-tables/eventlog-tables.js.map +1 -1
  232. package/dist/schema/state/sqlite/system-tables/state-tables.d.ts +328 -106
  233. package/dist/schema/state/sqlite/system-tables/state-tables.d.ts.map +1 -1
  234. package/dist/schema/state/sqlite/system-tables/state-tables.js +33 -1
  235. package/dist/schema/state/sqlite/system-tables/state-tables.js.map +1 -1
  236. package/dist/schema/state/sqlite/table-def.d.ts +16 -19
  237. package/dist/schema/state/sqlite/table-def.d.ts.map +1 -1
  238. package/dist/schema/state/sqlite/table-def.js +53 -3
  239. package/dist/schema/state/sqlite/table-def.js.map +1 -1
  240. package/dist/schema/state/sqlite/table-def.test.js +153 -36
  241. package/dist/schema/state/sqlite/table-def.test.js.map +1 -1
  242. package/dist/schema/unknown-events.d.ts.map +1 -1
  243. package/dist/schema/unknown-events.js +2 -1
  244. package/dist/schema/unknown-events.js.map +1 -1
  245. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js +2 -2
  246. package/dist/session-id-symbol.d.ts +29 -0
  247. package/dist/session-id-symbol.d.ts.map +1 -0
  248. package/dist/session-id-symbol.js +44 -0
  249. package/dist/session-id-symbol.js.map +1 -0
  250. package/dist/sql-queries/sql-queries.d.ts.map +1 -1
  251. package/dist/sql-queries/sql-queries.js +8 -10
  252. package/dist/sql-queries/sql-queries.js.map +1 -1
  253. package/dist/sql-queries/types.d.ts +6 -7
  254. package/dist/sql-queries/types.d.ts.map +1 -1
  255. package/dist/sql-queries/types.js.map +1 -1
  256. package/dist/sqlite-db-helper.d.ts +21 -1
  257. package/dist/sqlite-db-helper.d.ts.map +1 -1
  258. package/dist/sqlite-db-helper.js +37 -2
  259. package/dist/sqlite-db-helper.js.map +1 -1
  260. package/dist/sqlite-types.d.ts +3 -6
  261. package/dist/sqlite-types.d.ts.map +1 -1
  262. package/dist/sqlite-types.js +3 -3
  263. package/dist/sqlite-types.js.map +1 -1
  264. package/dist/sync/ClientSessionSyncProcessor.d.ts +38 -16
  265. package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
  266. package/dist/sync/ClientSessionSyncProcessor.js +196 -66
  267. package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
  268. package/dist/sync/errors.d.ts +12 -18
  269. package/dist/sync/errors.d.ts.map +1 -1
  270. package/dist/sync/errors.js +2 -2
  271. package/dist/sync/errors.js.map +1 -1
  272. package/dist/sync/mock-sync-backend.d.ts +2 -3
  273. package/dist/sync/mock-sync-backend.d.ts.map +1 -1
  274. package/dist/sync/mock-sync-backend.js +54 -33
  275. package/dist/sync/mock-sync-backend.js.map +1 -1
  276. package/dist/sync/mock-sync-backend.test.d.ts +2 -0
  277. package/dist/sync/mock-sync-backend.test.d.ts.map +1 -0
  278. package/dist/sync/mock-sync-backend.test.js +49 -0
  279. package/dist/sync/mock-sync-backend.test.js.map +1 -0
  280. package/dist/sync/next/history-dag-common.d.ts +4 -0
  281. package/dist/sync/next/history-dag-common.d.ts.map +1 -1
  282. package/dist/sync/next/history-dag-common.js +52 -31
  283. package/dist/sync/next/history-dag-common.js.map +1 -1
  284. package/dist/sync/next/history-dag.d.ts.map +1 -1
  285. package/dist/sync/next/history-dag.js +2 -1
  286. package/dist/sync/next/history-dag.js.map +1 -1
  287. package/dist/sync/next/test/compact-events.calculator.test.js +2 -2
  288. package/dist/sync/next/test/event-fixtures.d.ts +7 -7
  289. package/dist/sync/next/test/event-fixtures.js +1 -1
  290. package/dist/sync/next/test/event-fixtures.js.map +1 -1
  291. package/dist/sync/next/test/history-dag-common.test.d.ts +2 -0
  292. package/dist/sync/next/test/history-dag-common.test.d.ts.map +1 -0
  293. package/dist/sync/next/test/history-dag-common.test.js +73 -0
  294. package/dist/sync/next/test/history-dag-common.test.js.map +1 -0
  295. package/dist/sync/sync-backend-kv.d.ts.map +1 -1
  296. package/dist/sync/sync-backend-kv.js +4 -2
  297. package/dist/sync/sync-backend-kv.js.map +1 -1
  298. package/dist/sync/sync-backend.d.ts +15 -15
  299. package/dist/sync/sync-backend.d.ts.map +1 -1
  300. package/dist/sync/sync-backend.js +9 -5
  301. package/dist/sync/sync-backend.js.map +1 -1
  302. package/dist/sync/sync.d.ts +1 -1
  303. package/dist/sync/sync.d.ts.map +1 -1
  304. package/dist/sync/syncstate.d.ts +97 -173
  305. package/dist/sync/syncstate.d.ts.map +1 -1
  306. package/dist/sync/syncstate.js +34 -37
  307. package/dist/sync/syncstate.js.map +1 -1
  308. package/dist/sync/syncstate.test.js +100 -61
  309. package/dist/sync/syncstate.test.js.map +1 -1
  310. package/dist/sync/transport-chunking.d.ts +15 -16
  311. package/dist/sync/transport-chunking.d.ts.map +1 -1
  312. package/dist/sync/transport-chunking.js +23 -32
  313. package/dist/sync/transport-chunking.js.map +1 -1
  314. package/dist/util.d.ts +11 -4
  315. package/dist/util.d.ts.map +1 -1
  316. package/dist/util.js +19 -2
  317. package/dist/util.js.map +1 -1
  318. package/dist/version.d.ts.map +1 -1
  319. package/dist/version.js.map +1 -1
  320. package/package.json +19 -37
  321. package/src/ClientSessionLeaderThreadProxy.ts +1 -1
  322. package/src/MaterializationJournal.ts +184 -0
  323. package/src/StateHead.ts +80 -0
  324. package/src/WorkerTransportError.ts +4 -4
  325. package/src/__tests__/fixture.ts +3 -3
  326. package/src/adapter-types.ts +24 -61
  327. package/src/debug-info.ts +50 -70
  328. package/src/defs.ts +2 -2
  329. package/src/devtools/devtools-compatibility.test.ts +1 -0
  330. package/src/devtools/devtools-messages-client-session.ts +56 -65
  331. package/src/devtools/devtools-messages-common.ts +12 -11
  332. package/src/devtools/devtools-messages-leader.ts +71 -69
  333. package/src/devtools/devtools-sessioninfo.ts +13 -11
  334. package/src/devtools/mod.ts +4 -5
  335. package/src/errors.ts +46 -34
  336. package/src/index.ts +8 -1
  337. package/src/leader-thread/LeaderSyncProcessor.ts +794 -691
  338. package/src/leader-thread/RejectedPushError.ts +40 -27
  339. package/src/leader-thread/connection.ts +12 -8
  340. package/src/leader-thread/eventlog.ts +7 -7
  341. package/src/leader-thread/leader-worker-devtools.ts +37 -19
  342. package/src/leader-thread/make-leader-thread-layer.test.ts +7 -7
  343. package/src/leader-thread/make-leader-thread-layer.ts +56 -53
  344. package/src/leader-thread/materialize-event.ts +13 -8
  345. package/src/leader-thread/recreate-db.ts +24 -59
  346. package/src/leader-thread/shutdown-channel.ts +3 -14
  347. package/src/leader-thread/stream-events.ts +104 -101
  348. package/src/leader-thread/types.ts +24 -62
  349. package/src/logging.ts +5 -52
  350. package/src/make-client-session.ts +6 -6
  351. package/src/materializer-helper.ts +8 -37
  352. package/src/otel.ts +5 -14
  353. package/src/rematerialize-from-eventlog.ts +97 -94
  354. package/src/schema/EventDef/define.test.ts +28 -0
  355. package/src/schema/EventDef/define.ts +20 -19
  356. package/src/schema/EventDef/deprecated.test.ts +1 -8
  357. package/src/schema/EventDef/deprecated.ts +17 -20
  358. package/src/schema/EventDef/event-def.ts +2 -4
  359. package/src/schema/EventSequenceNumber/client.ts +8 -9
  360. package/src/schema/EventSequenceNumber/global.ts +1 -1
  361. package/src/schema/EventSequenceNumber.test.ts +5 -5
  362. package/src/schema/LiveStoreEvent/client.test.ts +17 -4
  363. package/src/schema/LiveStoreEvent/client.ts +36 -35
  364. package/src/schema/LiveStoreEvent/for-event-def.ts +7 -7
  365. package/src/schema/LiveStoreEvent/global.ts +1 -1
  366. package/src/schema/LiveStoreEvent/input.ts +6 -6
  367. package/src/schema/mod.ts +1 -0
  368. package/src/schema/schema.ts +3 -2
  369. package/src/schema/state/sqlite/client-document-def.test.ts +32 -13
  370. package/src/schema/state/sqlite/client-document-def.ts +95 -80
  371. package/src/schema/state/sqlite/column-annotations.test.ts +26 -45
  372. package/src/schema/state/sqlite/column-annotations.ts +26 -30
  373. package/src/schema/state/sqlite/column-def.test.ts +132 -77
  374. package/src/schema/state/sqlite/column-def.ts +72 -37
  375. package/src/schema/state/sqlite/column-spec.test.ts +2 -2
  376. package/src/schema/state/sqlite/column-spec.ts +3 -2
  377. package/src/schema/state/sqlite/db-schema/ast/sqlite.ts +15 -5
  378. package/src/schema/state/sqlite/db-schema/dsl/__snapshots__/field-defs.test.ts.snap +123 -63
  379. package/src/schema/state/sqlite/db-schema/dsl/field-defs.test.ts +35 -16
  380. package/src/schema/state/sqlite/db-schema/dsl/field-defs.ts +25 -31
  381. package/src/schema/state/sqlite/db-schema/dsl/mod.ts +35 -21
  382. package/src/schema/state/sqlite/mod.ts +2 -4
  383. package/src/schema/state/sqlite/persistence.ts +11 -0
  384. package/src/schema/state/sqlite/query-builder/api.ts +9 -9
  385. package/src/schema/state/sqlite/query-builder/astToSql.ts +31 -26
  386. package/src/schema/state/sqlite/query-builder/impl.test.ts +433 -669
  387. package/src/schema/state/sqlite/query-builder/impl.ts +19 -15
  388. package/src/schema/state/sqlite/schema-helpers.ts +1 -1
  389. package/src/schema/state/sqlite/system-tables/eventlog-tables.ts +2 -2
  390. package/src/schema/state/sqlite/system-tables/state-tables.ts +41 -1
  391. package/src/schema/state/sqlite/table-def.test.ts +204 -66
  392. package/src/schema/state/sqlite/table-def.ts +96 -45
  393. package/src/schema/unknown-events.ts +3 -2
  394. package/src/schema-management/__tests__/migrations-autoincrement-quoting.test.ts +2 -2
  395. package/src/session-id-symbol.ts +59 -0
  396. package/src/sql-queries/sql-queries.ts +8 -12
  397. package/src/sql-queries/types.ts +6 -7
  398. package/src/sqlite-db-helper.ts +64 -2
  399. package/src/sqlite-types.ts +5 -8
  400. package/src/sync/ClientSessionSyncProcessor.ts +303 -119
  401. package/src/sync/errors.ts +14 -12
  402. package/src/sync/mock-sync-backend.test.ts +78 -0
  403. package/src/sync/mock-sync-backend.ts +93 -47
  404. package/src/sync/next/history-dag-common.ts +60 -34
  405. package/src/sync/next/history-dag.ts +4 -1
  406. package/src/sync/next/test/compact-events.calculator.test.ts +2 -2
  407. package/src/sync/next/test/event-fixtures.ts +1 -1
  408. package/src/sync/next/test/history-dag-common.test.ts +87 -0
  409. package/src/sync/sync-backend-kv.ts +4 -2
  410. package/src/sync/sync-backend.ts +15 -15
  411. package/src/sync/sync.ts +1 -1
  412. package/src/sync/syncstate.test.ts +191 -140
  413. package/src/sync/syncstate.ts +63 -53
  414. package/src/sync/transport-chunking.ts +34 -39
  415. package/src/util.ts +18 -9
  416. package/src/version.ts +1 -2
  417. package/dist/sql-queries/misc.d.ts +0 -2
  418. package/dist/sql-queries/misc.d.ts.map +0 -1
  419. package/dist/sql-queries/misc.js +0 -2
  420. package/dist/sql-queries/misc.js.map +0 -1
  421. package/src/sql-queries/misc.ts +0 -2
@@ -1,5 +1,4 @@
1
- import type { Scope, SubscriptionRef } from '@livestore/utils/effect'
2
- import { Effect, Stream } from '@livestore/utils/effect'
1
+ import { type Scope, type SubscriptionRef, Effect, Latch, Stream } from '@livestore/utils/effect'
3
2
  import * as Webmesh from '@livestore/webmesh'
4
3
 
5
4
  import type {
@@ -51,9 +50,10 @@ export const makeClientSession = <R>({
51
50
  origin: string | undefined
52
51
  }): Effect.Effect<ClientSession, never, Scope.Scope | R> =>
53
52
  Effect.gen(function* () {
54
- const devtools: ClientSession['devtools'] = devtoolsEnabled === true
55
- ? { enabled: true, pullLatch: yield* Effect.makeLatch(true), pushLatch: yield* Effect.makeLatch(true) }
56
- : { enabled: false }
53
+ const devtools: ClientSession['devtools'] =
54
+ devtoolsEnabled === true
55
+ ? { enabled: true, pullLatch: yield* Latch.make(true), pushLatch: yield* Latch.make(true) }
56
+ : { enabled: false }
57
57
 
58
58
  if (devtoolsEnabled === true) {
59
59
  yield* Effect.gen(function* () {
@@ -116,7 +116,7 @@ export const makeClientSession = <R>({
116
116
  yield* connectDevtoolsToStore(clientSessionDevtoolsChannel)
117
117
  },
118
118
  Effect.tapCauseLogPretty,
119
- Effect.forkScoped,
119
+ Effect.forkScoped(),
120
120
  ),
121
121
  ),
122
122
  Stream.runDrain,
@@ -1,8 +1,7 @@
1
- import { isDevEnv, isNil, isReadonlyArray } from '@livestore/utils'
2
- import { Hash, Option, Schema } from '@livestore/utils/effect'
1
+ import { isDevEnv } from '@livestore/utils'
2
+ import { Hash, Option, Predicate, ReadonlyArray, Schema } from '@livestore/utils/effect'
3
3
 
4
4
  import type { SqliteDb } from './adapter-types.ts'
5
- import { SessionIdSymbol } from './adapter-types.ts'
6
5
  import type { EventDef, Materializer, MaterializerContextQuery, MaterializerResult } from './schema/EventDef/mod.ts'
7
6
  import type * as LiveStoreEvent from './schema/LiveStoreEvent/mod.ts'
8
7
  import type { LiveStoreSchema } from './schema/schema.ts'
@@ -39,9 +38,10 @@ export const getExecStatementsFromMaterializer = ({
39
38
  }
40
39
  : event.decoded
41
40
 
42
- const eventArgsEncoded = isNil(event.decoded?.args) === true
43
- ? undefined
44
- : Schema.encodeUnknownSync(eventDef.schema)(event.decoded.args)
41
+ const eventArgsEncoded =
42
+ Predicate.isNotUndefined(event.decoded) === true && Predicate.isNotNullish(event.decoded.args) === true
43
+ ? Schema.encodeUnknownSync(eventDef.schema)(event.decoded.args)
44
+ : undefined
45
45
 
46
46
  const query: MaterializerContextQuery = (
47
47
  rawQueryOrQueryBuilder:
@@ -55,7 +55,7 @@ export const getExecStatementsFromMaterializer = ({
55
55
  const { query, bindValues } = rawQueryOrQueryBuilder.asSql()
56
56
  const rawResults = dbState.select(query, prepareBindValues(bindValues, query))
57
57
  const resultSchema = getResultSchema(rawQueryOrQueryBuilder)
58
- return Schema.decodeSync(resultSchema)(rawResults)
58
+ return Schema.decodeUnknownSync(resultSchema)(rawResults)
59
59
  } else {
60
60
  const { query, bindValues } = rawQueryOrQueryBuilder
61
61
  return dbState.select(query, prepareBindValues(bindValues, query))
@@ -126,7 +126,7 @@ const fromMaterializerResult = (
126
126
  bindValues: BindValues
127
127
  writeTables: ReadonlySet<string> | undefined
128
128
  }> => {
129
- if (isReadonlyArray(materializerResult) === true) {
129
+ if (ReadonlyArray.isArray<MaterializerResult | ReadonlyArray<MaterializerResult>>(materializerResult) === true) {
130
130
  return materializerResult.flatMap(fromMaterializerResult)
131
131
  }
132
132
  if (isQueryBuilder(materializerResult) === true) {
@@ -144,32 +144,3 @@ const fromMaterializerResult = (
144
144
  ]
145
145
  }
146
146
  }
147
-
148
- // NOTE we should explore whether there is a more elegant solution
149
- // e.g. by leveraging the schema to replace the sessionIdSymbol
150
- export const replaceSessionIdSymbol = (
151
- bindValues: Record<string, unknown> | ReadonlyArray<unknown>,
152
- sessionId: string,
153
- ) => {
154
- deepReplaceValue(bindValues, SessionIdSymbol, sessionId)
155
- }
156
-
157
- const deepReplaceValue = <S, R>(input: any, searchValue: S, replaceValue: R): void => {
158
- if (Array.isArray(input) === true) {
159
- for (const i in input) {
160
- if (input[i] === searchValue) {
161
- input[i] = replaceValue
162
- } else {
163
- deepReplaceValue(input[i], searchValue, replaceValue)
164
- }
165
- }
166
- } else if (typeof input === 'object' && input !== null) {
167
- for (const key in input) {
168
- if (input[key] === searchValue) {
169
- input[key] = replaceValue
170
- } else {
171
- deepReplaceValue(input[key], searchValue, replaceValue)
172
- }
173
- }
174
- }
175
- }
package/src/otel.ts CHANGED
@@ -1,26 +1,25 @@
1
1
  import * as otel from '@opentelemetry/api'
2
2
 
3
3
  import { makeNoopTracer } from '@livestore/utils'
4
+ import type { Tracer } from '@livestore/utils/effect'
4
5
  import { Effect, identity, Layer, OtelTracer } from '@livestore/utils/effect'
5
6
 
6
7
  export const OtelLiveDummy: Layer.Layer<OtelTracer.OtelTracer> = Layer.suspend(() => {
7
8
  const OtelTracerLive = Layer.succeed(OtelTracer.OtelTracer, makeNoopTracer())
8
9
 
9
- const TracingLive = Layer.unwrapEffect(Effect.map(OtelTracer.make, Layer.setTracer)).pipe(
10
- Layer.provideMerge(OtelTracerLive),
11
- )
10
+ const TracingLive = OtelTracer.layerWithoutOtelTracer.pipe(Layer.provideMerge(OtelTracerLive))
12
11
 
13
12
  return TracingLive
14
13
  })
15
14
 
16
15
  export const provideOtel =
17
16
  ({ otelTracer, parentSpanContext }: { otelTracer?: otel.Tracer; parentSpanContext?: otel.Context }) =>
18
- <A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, Exclude<R, OtelTracer.OtelTracer>> => {
17
+ <A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, E, Exclude<R, OtelTracer.OtelTracer | Tracer.Tracer>> => {
19
18
  const OtelTracerLive = Layer.succeed(OtelTracer.OtelTracer, otelTracer ?? makeNoopTracer())
20
19
 
21
- const TracingLive = Layer.unwrapEffect(Effect.map(OtelTracer.make, Layer.setTracer)).pipe(
20
+ const TracingLive = OtelTracer.layerWithoutOtelTracer.pipe(
22
21
  Layer.provideMerge(OtelTracerLive),
23
- ) as any as Layer.Layer<OtelTracer.OtelTracer>
22
+ ) as any as Layer.Layer<OtelTracer.OtelTracer | Tracer.Tracer>
24
23
 
25
24
  return effect.pipe(
26
25
  parentSpanContext !== undefined
@@ -29,11 +28,3 @@ export const provideOtel =
29
28
  Effect.provide(TracingLive),
30
29
  )
31
30
  }
32
-
33
- export const getDurationMsFromSpan = (span: otel.Span): number => {
34
- const durationHr: [seconds: number, nanos: number] = (span as any)._duration
35
- return durationHr[0] * 1000 + durationHr[1] / 1_000_000
36
- }
37
-
38
- export const getStartTimeHighResFromSpan = (span: otel.Span): DOMHighResTimeStamp =>
39
- (span as any)._performanceStartTime as DOMHighResTimeStamp
@@ -1,15 +1,15 @@
1
1
  import { memoizeByRef } from '@livestore/utils'
2
- import { Chunk, Effect, Option, Schema, Stream } from '@livestore/utils/effect'
2
+ import { Effect, Option, ReadonlyArray as EffectArray, Schema, Stream } from '@livestore/utils/effect'
3
3
 
4
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, LiveStoreEvent, resolveEventDef, SystemTables } from './schema/mod.ts'
7
+ import { EventSequenceNumber, LiveStoreEvent, SystemTables } from './schema/mod.ts'
8
8
  import type { PreparedBindValues } from './util.ts'
9
9
  import { sql } from './util.ts'
10
10
 
11
11
  /** Parse JSON string to unknown value */
12
- const jsonParse = Schema.decodeUnknownSync(Schema.parseJson())
12
+ const jsonParse = Schema.decodeUnknownSync(Schema.fromJsonString(Schema.Unknown))
13
13
 
14
14
  export const rematerializeFromEventlog = Effect.fn('@livestore/common:rematerializeFromEventlog')(function* ({
15
15
  dbEventlog,
@@ -25,111 +25,114 @@ export const rematerializeFromEventlog = Effect.fn('@livestore/common:rematerial
25
25
  onProgress: (_: { done: number; total: number }) => Effect.Effect<void>
26
26
  materializeEvent: MaterializeEvent
27
27
  }) {
28
- const eventsCount = dbEventlog.select<{ count: number }>(
29
- `SELECT COUNT(*) AS count FROM ${SystemTables.EVENTLOG_META_TABLE}`,
30
- )[0]!.count
31
-
32
- const hashEventDef = memoizeByRef((event: EventDef.AnyWithoutFn) => Schema.hash(event.schema))
33
-
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
- })
54
-
55
- const resolution = yield* resolveEventDef(schema, {
56
- operation: '@livestore/common:rematerializeFromEventlog:processEvent',
57
- event: eventEncoded,
58
- }).pipe(UnknownError.mapToUnknownError)
59
-
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
- }
28
+ const eventsCount = dbEventlog.select<{ count: number }>(
29
+ `SELECT COUNT(*) AS count FROM ${SystemTables.EVENTLOG_META_TABLE}`,
30
+ )[0]!.count
31
+
32
+ const hashEventDef = memoizeByRef((event: EventDef.AnyWithoutFn) => Schema.hash(event.schema))
33
+
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
+ })
65
54
 
66
- const { eventDef } = resolution
55
+ const eventDef = schema.eventsDefsMap.get(row.name)
56
+ const materializer = schema.state.materializers.get(row.name)
67
57
 
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
- }
58
+ if (eventDef === undefined || materializer === undefined) {
59
+ // Route unknown events through the normal materialization boundary so
60
+ // they advance the state snapshot head as no-ops.
61
+ yield* materializeEvent(eventEncoded, { skipEventlog: true })
62
+ return
63
+ }
73
64
 
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: `\
65
+ if (hashEventDef(eventDef) !== row.schemaHash) {
66
+ yield* Effect.logWarning(
67
+ `Schema hash mismatch for event definition ${row.name}. Trying to materialize event anyway.`,
68
+ )
69
+ }
70
+
71
+ // Checking whether the schema has changed in an incompatible way
72
+ yield* Schema.decodeUnknownEffect(eventDef.schema)(args).pipe(
73
+ Effect.mapError((cause) =>
74
+ UnknownError.make({
75
+ cause,
76
+ note: `\
80
77
  There was an error during rematerializing from the eventlog while decoding
81
78
  the persisted event args for event definition "${row.name}".
82
79
  This likely means the schema has changed in an incompatible way.
83
80
  `,
84
- }),
85
- ),
86
- )
81
+ }),
82
+ ),
83
+ )
87
84
 
88
- yield* materializeEvent(eventEncoded, { skipEventlog: true })
89
- })
85
+ yield* materializeEvent(eventEncoded, { skipEventlog: true })
86
+ })
90
87
 
91
- const CHUNK_SIZE = 100
88
+ const CHUNK_SIZE = 100
92
89
 
93
- const stmt = dbEventlog.prepare(sql`\
90
+ const stmt = dbEventlog.prepare(sql`\
94
91
  SELECT * FROM ${SystemTables.EVENTLOG_META_TABLE}
95
92
  WHERE seqNumGlobal > $seqNumGlobal OR (seqNumGlobal = $seqNumGlobal AND seqNumClient > $seqNumClient)
96
93
  ORDER BY seqNumGlobal ASC, seqNumClient ASC
97
94
  LIMIT ${CHUNK_SIZE}
98
95
  `)
99
96
 
100
- let processedEvents = 0
101
-
102
- yield* Stream.unfoldChunk<
103
- Chunk.Chunk<SystemTables.EventlogMetaRow> | { _tag: 'Initial' },
104
- SystemTables.EventlogMetaRow
105
- >({ _tag: 'Initial' }, (item) => {
106
- // End stream if no more rows
107
- if (Chunk.isChunk(item) === true && item.length === 0) return Option.none()
108
-
109
- const lastId = Chunk.isChunk(item) === true
110
- ? Chunk.last(item).pipe(
111
- Option.map((_) => ({ global: _.seqNumGlobal, client: _.seqNumClient })),
112
- Option.getOrElse(() => EventSequenceNumber.Client.ROOT),
113
- )
114
- : EventSequenceNumber.Client.ROOT
115
- const nextItem = Chunk.fromIterable(
116
- stmt.select<SystemTables.EventlogMetaRow>({
117
- $seqNumGlobal: lastId?.global,
118
- $seqNumClient: lastId?.client,
119
- } as any as PreparedBindValues),
120
- )
121
- const prevItem = Chunk.isChunk(item) === true ? item : Chunk.empty()
122
- return Option.some([prevItem, nextItem])
123
- }).pipe(
124
- Stream.bufferChunks({ capacity: 2 }),
125
- Stream.tap((row) =>
126
- Effect.gen(function* () {
127
- yield* processEvent(row)
128
-
129
- processedEvents++
130
- yield* onProgress({ done: processedEvents, total: eventsCount })
131
- }),
132
- ),
133
- Stream.runDrain,
134
- )
97
+ let processedEvents = 0
98
+
99
+ yield* Stream.paginate(EventSequenceNumber.Client.ROOT, (lastId) =>
100
+ Effect.sync(() => {
101
+ const rows = stmt.select<SystemTables.EventlogMetaRow>({
102
+ $seqNumGlobal: lastId.global,
103
+ $seqNumClient: lastId.client,
104
+ } as any as PreparedBindValues)
105
+
106
+ if (EffectArray.isReadonlyArrayNonEmpty(rows) === false) {
107
+ const done: readonly [
108
+ ReadonlyArray<SystemTables.EventlogMetaRow>,
109
+ Option.Option<EventSequenceNumber.Client.Composite>,
110
+ ] = [rows, Option.none()]
111
+ return done
112
+ }
113
+
114
+ const lastRow = EffectArray.lastNonEmpty(rows)
115
+ const nextCursor = EventSequenceNumber.Client.Composite.make({
116
+ global: lastRow.seqNumGlobal,
117
+ client: lastRow.seqNumClient,
118
+ rebaseGeneration: lastRow.seqNumRebaseGeneration,
119
+ })
120
+ const next: readonly [
121
+ ReadonlyArray<SystemTables.EventlogMetaRow>,
122
+ Option.Option<EventSequenceNumber.Client.Composite>,
123
+ ] = [rows, Option.some(nextCursor)]
124
+ return next
125
+ }),
126
+ ).pipe(
127
+ Stream.bufferArray({ capacity: 2 }),
128
+ Stream.tap((row) =>
129
+ Effect.gen(function* () {
130
+ yield* processEvent(row)
131
+
132
+ processedEvents++
133
+ yield* onProgress({ done: processedEvents, total: eventsCount })
134
+ }),
135
+ ),
136
+ Stream.runDrain,
137
+ )
135
138
  }, Effect.withPerformanceMeasure('@livestore/common:rematerializeFromEventlog'))
@@ -0,0 +1,28 @@
1
+ import { describe, expect, test } from 'vitest'
2
+
3
+ import { Schema } from '@livestore/utils/effect'
4
+
5
+ import { synced } from './define.ts'
6
+
7
+ describe('synced event wire schema', () => {
8
+ const occurredAt = new Date('2026-07-17T10:15:30.000Z')
9
+ const event = synced({
10
+ name: 'v1.Occurred',
11
+ schema: Schema.Struct({
12
+ occurredAt: Schema.DateFromString,
13
+ }),
14
+ })
15
+ const jsonSchema = Schema.fromJsonString(event.schema)
16
+
17
+ test('roundtrips a valid date through JSON', () => {
18
+ const encoded = Schema.encodeSync(jsonSchema)({ occurredAt })
19
+
20
+ expect(encoded).toBe('{"occurredAt":"2026-07-17T10:15:30.000Z"}')
21
+ expect(Schema.decodeSync(jsonSchema)(encoded)).toEqual({ occurredAt })
22
+ })
23
+
24
+ test('rejects invalid dates on encode and decode', () => {
25
+ expect(() => Schema.encodeSync(jsonSchema)({ occurredAt: new Date(Number.NaN) })).toThrow()
26
+ expect(() => Schema.decodeSync(jsonSchema)('{"occurredAt":"not-a-date"}')).toThrow()
27
+ })
28
+ })
@@ -29,7 +29,7 @@
29
29
  */
30
30
 
31
31
  import { shouldNeverHappen } from '@livestore/utils'
32
- import { Schema } from '@livestore/utils/effect'
32
+ import { Result, Schema } from '@livestore/utils/effect'
33
33
 
34
34
  import type { EventDef } from './event-def.ts'
35
35
  import type { EventDefFactInput, EventDefFacts } from './facts.ts'
@@ -105,15 +105,15 @@ export type DefineEventOptions<TTo, TDerived extends boolean = false> = {
105
105
  export const defineEvent = <TName extends string, TType, TEncoded = TType, TDerived extends boolean = false>(
106
106
  args: {
107
107
  name: TName
108
- schema: Schema.Schema<TType, TEncoded>
108
+ schema: Schema.Codec<TType, TEncoded>
109
109
  } & DefineEventOptions<TType, TDerived>,
110
110
  ): EventDef<TName, TType, TEncoded, TDerived> => {
111
111
  const { name, schema, ...options } = args
112
112
 
113
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')
114
+ const res = Schema.decodeResult(Schema.toType(schema))(args)
115
+ if (Result.isFailure(res) === true) {
116
+ shouldNeverHappen(`Invalid event args for event '${name}':`, res.failure.message, '\n')
117
117
  }
118
118
  return { name: name, args }
119
119
  }
@@ -127,18 +127,19 @@ export const defineEvent = <TName extends string, TType, TEncoded = TType, TDeri
127
127
  Object.defineProperty(makePartialEvent, 'options', {
128
128
  value: {
129
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(),
130
+ facts:
131
+ options?.facts !== undefined
132
+ ? (args, currentFacts) => {
133
+ const res = options.facts!(args, currentFacts)
134
+ return {
135
+ modify: {
136
+ set: res.modify?.set !== undefined ? new Set(res.modify.set) : new Set(),
137
+ unset: res.modify?.unset !== undefined ? new Set(res.modify.unset) : new Set(),
138
+ },
139
+ require: res.require !== undefined ? new Set(res.require) : new Set(),
140
+ }
139
141
  }
140
- }
141
- : undefined,
142
+ : undefined,
142
143
  derived: options?.derived ?? false,
143
144
  deprecated: options?.deprecated,
144
145
  } satisfies EventDef.Any['options'],
@@ -178,7 +179,7 @@ export const defineEvent = <TName extends string, TType, TEncoded = TType, TDeri
178
179
  export const synced = <TName extends string, TType, TEncoded = TType>(
179
180
  args: {
180
181
  name: TName
181
- schema: Schema.Schema<TType, TEncoded>
182
+ schema: Schema.Codec<TType, TEncoded>
182
183
  } & Omit<DefineEventOptions<TType>, 'derived' | 'clientOnly'>,
183
184
  ): EventDef<TName, TType, TEncoded> => defineEvent({ ...args, clientOnly: false })
184
185
 
@@ -201,7 +202,7 @@ export const synced = <TName extends string, TType, TEncoded = TType>(
201
202
  * name: 'UiStateSet',
202
203
  * schema: Schema.Struct({
203
204
  * selectedTodoId: Schema.NullOr(Schema.String),
204
- * filterMode: Schema.Literal('all', 'active', 'completed'),
205
+ * filterMode: Schema.Literals(['all', 'active', 'completed']),
205
206
  * }),
206
207
  * })
207
208
  *
@@ -212,6 +213,6 @@ export const synced = <TName extends string, TType, TEncoded = TType>(
212
213
  export const clientOnly = <TName extends string, TType, TEncoded = TType>(
213
214
  args: {
214
215
  name: TName
215
- schema: Schema.Schema<TType, TEncoded>
216
+ schema: Schema.Codec<TType, TEncoded>
216
217
  } & Omit<DefineEventOptions<TType>, 'derived' | 'clientOnly'>,
217
218
  ): EventDef<TName, TType, TEncoded> => defineEvent({ ...args, clientOnly: true })
@@ -60,14 +60,7 @@ describe('logDeprecationWarnings', () => {
60
60
 
61
61
  const run = (effect: Effect.Effect<void>) =>
62
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
- ),
63
+ effect.pipe(Effect.provide(Logger.layer([Logger.make(({ message }) => logs.push(message as unknown[]))]))),
71
64
  )
72
65
 
73
66
  test('logs event deprecation warning', () => {
@@ -30,20 +30,19 @@
30
30
  * @module
31
31
  */
32
32
 
33
- import type { Schema } from '@livestore/utils/effect'
34
- import { Effect, Option, SchemaAST } from '@livestore/utils/effect'
33
+ import { type Schema, Effect, Option, SchemaAST } from '@livestore/utils/effect'
35
34
 
36
35
  import type { EventDef } from './event-def.ts'
37
36
 
38
- /** Symbol used to mark schemas as deprecated. */
39
- export const DeprecatedId = Symbol.for('livestore/schema/annotations/deprecated')
37
+ /** Annotation key used to mark schemas as deprecated. */
38
+ export const DeprecatedId = 'livestore/schema/annotations/deprecated'
40
39
 
41
40
  /**
42
41
  * Marks a schema field as deprecated with a reason message.
43
42
  * When an event is committed with a deprecated field that has a value,
44
43
  * a warning will be logged.
45
44
  *
46
- * Works with both Schema types and PropertySignatures (from Schema.optional).
45
+ * Works with Schema fields, including optional fields from Schema.optional.
47
46
  *
48
47
  * @param reason - Explanation of why this field is deprecated and what to use instead
49
48
  * @returns A function that adds the deprecation annotation to the schema
@@ -58,8 +57,8 @@ export const DeprecatedId = Symbol.for('livestore/schema/annotations/deprecated'
58
57
  */
59
58
  export const deprecated =
60
59
  (reason: string) =>
61
- <T extends { annotations: (annotations: { readonly [DeprecatedId]?: string }) => T }>(schema: T): T =>
62
- schema.annotations({ [DeprecatedId]: reason })
60
+ <T extends Schema.Top>(schema: T): T['Rebuild'] =>
61
+ schema.annotate({ [DeprecatedId]: reason })
63
62
 
64
63
  /**
65
64
  * Checks if a schema has a deprecation annotation.
@@ -67,8 +66,8 @@ export const deprecated =
67
66
  * @param schema - The schema to check
68
67
  * @returns The deprecation reason if deprecated, None otherwise
69
68
  */
70
- export const getDeprecatedReason = <A, I, R>(schema: Schema.Schema<A, I, R>): Option.Option<string> =>
71
- SchemaAST.getAnnotation<string>(DeprecatedId)(schema.ast)
69
+ export const getDeprecatedReason = (schema: Schema.Top): Option.Option<string> =>
70
+ Option.fromUndefinedOr(SchemaAST.resolveAt<string>(DeprecatedId)(schema.ast))
72
71
 
73
72
  /**
74
73
  * Checks if a schema is deprecated.
@@ -76,8 +75,7 @@ export const getDeprecatedReason = <A, I, R>(schema: Schema.Schema<A, I, R>): Op
76
75
  * @param schema - The schema to check
77
76
  * @returns true if the schema is deprecated
78
77
  */
79
- export const isDeprecated = <A, I, R>(schema: Schema.Schema<A, I, R>): boolean =>
80
- Option.isSome(getDeprecatedReason(schema))
78
+ export const isDeprecated = (schema: Schema.Top): boolean => Option.isSome(getDeprecatedReason(schema))
81
79
 
82
80
  /**
83
81
  * Finds deprecated fields with values in the given event arguments.
@@ -88,28 +86,27 @@ export const isDeprecated = <A, I, R>(schema: Schema.Schema<A, I, R>): boolean =
88
86
  * @returns Array of objects containing field name and deprecation reason
89
87
  */
90
88
  export const findDeprecatedFieldsWithValues = (
91
- schema: Schema.Schema.All,
89
+ schema: Schema.Top,
92
90
  args: Record<string, unknown>,
93
91
  ): Array<{ field: string; reason: string }> => {
94
92
  const result: Array<{ field: string; reason: string }> = []
95
- const ast = schema.ast
93
+ const ast = SchemaAST.toType(schema.ast)
96
94
 
97
- // Handle TypeLiteral (Struct) schemas
98
- if (ast._tag === 'TypeLiteral') {
95
+ // Handle Objects (Struct) schemas
96
+ if (SchemaAST.isObjects(ast) === true) {
99
97
  for (const prop of ast.propertySignatures) {
100
98
  const fieldName = String(prop.name)
101
99
  const fieldValue = args[fieldName]
102
100
 
103
101
  // Only check fields that have a value (not undefined)
104
102
  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
103
+ // Check deprecation on the property key itself (for Schema.optional(...).pipe(deprecated(...)))
104
+ const deprecationReason = prop.type.context?.annotations?.[DeprecatedId] as string | undefined
108
105
 
109
106
  // Also check deprecation on the type (for direct field deprecation)
110
- const typeDeprecation = SchemaAST.getAnnotation<string>(DeprecatedId)(prop.type)
107
+ const typeDeprecation = SchemaAST.resolveAt<string>(DeprecatedId)(prop.type)
111
108
 
112
- const reason = deprecationReason ?? (Option.isSome(typeDeprecation) === true ? typeDeprecation.value : undefined)
109
+ const reason = deprecationReason ?? typeDeprecation
113
110
  if (reason !== undefined) {
114
111
  result.push({ field: fieldName, reason })
115
112
  }
@@ -34,7 +34,7 @@ export type EventDef<TName extends string, TType, TEncoded = TType, TDerived ext
34
34
  name: TName
35
35
 
36
36
  /** Effect Schema used for validating and encoding/decoding event arguments. */
37
- schema: Schema.Schema<TType, TEncoded>
37
+ schema: Schema.Codec<TType, TEncoded>
38
38
 
39
39
  options: {
40
40
  /**
@@ -62,9 +62,7 @@ export type EventDef<TName extends string, TType, TEncoded = TType, TDerived ext
62
62
  * Callable signature - creates a partial event with decoded arguments.
63
63
  * The returned object can be passed directly to `store.commit()`.
64
64
  */
65
- (
66
- args: TType,
67
- ): {
65
+ (args: TType): {
68
66
  name: TName
69
67
  args: TType
70
68
  }