@livestore/common 0.4.0-dev.8 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (518) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/ClientSessionLeaderThreadProxy.d.ts +27 -12
  3. package/dist/ClientSessionLeaderThreadProxy.d.ts.map +1 -1
  4. package/dist/ClientSessionLeaderThreadProxy.js.map +1 -1
  5. package/dist/WorkerTransportError.d.ts +11 -0
  6. package/dist/WorkerTransportError.d.ts.map +1 -0
  7. package/dist/WorkerTransportError.js +11 -0
  8. package/dist/WorkerTransportError.js.map +1 -0
  9. package/dist/adapter-types.d.ts +37 -7
  10. package/dist/adapter-types.d.ts.map +1 -1
  11. package/dist/adapter-types.js +27 -1
  12. package/dist/adapter-types.js.map +1 -1
  13. package/dist/bounded-collections.d.ts.map +1 -1
  14. package/dist/bounded-collections.js +6 -4
  15. package/dist/bounded-collections.js.map +1 -1
  16. package/dist/debug-info.d.ts.map +1 -1
  17. package/dist/debug-info.js +33 -6
  18. package/dist/debug-info.js.map +1 -1
  19. package/dist/devtools/devtools-compatibility.test.d.ts +2 -0
  20. package/dist/devtools/devtools-compatibility.test.d.ts.map +1 -0
  21. package/dist/devtools/devtools-compatibility.test.js +15 -0
  22. package/dist/devtools/devtools-compatibility.test.js.map +1 -0
  23. package/dist/devtools/devtools-messages-client-session.d.ts +55 -24
  24. package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -1
  25. package/dist/devtools/devtools-messages-client-session.js +22 -5
  26. package/dist/devtools/devtools-messages-client-session.js.map +1 -1
  27. package/dist/devtools/devtools-messages-common.d.ts +11 -14
  28. package/dist/devtools/devtools-messages-common.d.ts.map +1 -1
  29. package/dist/devtools/devtools-messages-common.js +7 -9
  30. package/dist/devtools/devtools-messages-common.js.map +1 -1
  31. package/dist/devtools/devtools-messages-leader.d.ts +65 -30
  32. package/dist/devtools/devtools-messages-leader.d.ts.map +1 -1
  33. package/dist/devtools/devtools-messages-leader.js +29 -11
  34. package/dist/devtools/devtools-messages-leader.js.map +1 -1
  35. package/dist/devtools/devtools-sessioninfo.d.ts +14 -2
  36. package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -1
  37. package/dist/devtools/devtools-sessioninfo.js +7 -4
  38. package/dist/devtools/devtools-sessioninfo.js.map +1 -1
  39. package/dist/devtools/mod.d.ts +13 -2
  40. package/dist/devtools/mod.d.ts.map +1 -1
  41. package/dist/devtools/mod.js +10 -3
  42. package/dist/devtools/mod.js.map +1 -1
  43. package/dist/errors.d.ts +48 -18
  44. package/dist/errors.d.ts.map +1 -1
  45. package/dist/errors.js +20 -12
  46. package/dist/errors.js.map +1 -1
  47. package/dist/index.d.ts +4 -1
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +4 -1
  50. package/dist/index.js.map +1 -1
  51. package/dist/leader-thread/LeaderSyncProcessor.d.ts +53 -6
  52. package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
  53. package/dist/leader-thread/LeaderSyncProcessor.js +325 -257
  54. package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
  55. package/dist/leader-thread/RejectedPushError.d.ts +107 -0
  56. package/dist/leader-thread/RejectedPushError.d.ts.map +1 -0
  57. package/dist/leader-thread/RejectedPushError.js +78 -0
  58. package/dist/leader-thread/RejectedPushError.js.map +1 -0
  59. package/dist/leader-thread/connection.js +1 -1
  60. package/dist/leader-thread/connection.js.map +1 -1
  61. package/dist/leader-thread/eventlog.d.ts +19 -14
  62. package/dist/leader-thread/eventlog.d.ts.map +1 -1
  63. package/dist/leader-thread/eventlog.js +78 -18
  64. package/dist/leader-thread/eventlog.js.map +1 -1
  65. package/dist/leader-thread/leader-worker-devtools.d.ts +1 -2
  66. package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
  67. package/dist/leader-thread/leader-worker-devtools.js +90 -58
  68. package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
  69. package/dist/leader-thread/make-leader-thread-layer.d.ts +15 -7
  70. package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
  71. package/dist/leader-thread/make-leader-thread-layer.js +49 -17
  72. package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
  73. package/dist/leader-thread/make-leader-thread-layer.test.d.ts +2 -0
  74. package/dist/leader-thread/make-leader-thread-layer.test.d.ts.map +1 -0
  75. package/dist/leader-thread/make-leader-thread-layer.test.js +32 -0
  76. package/dist/leader-thread/make-leader-thread-layer.test.js.map +1 -0
  77. package/dist/leader-thread/materialize-event.d.ts +1 -1
  78. package/dist/leader-thread/materialize-event.d.ts.map +1 -1
  79. package/dist/leader-thread/materialize-event.js +28 -9
  80. package/dist/leader-thread/materialize-event.js.map +1 -1
  81. package/dist/leader-thread/mod.d.ts +1 -0
  82. package/dist/leader-thread/mod.d.ts.map +1 -1
  83. package/dist/leader-thread/mod.js +1 -0
  84. package/dist/leader-thread/mod.js.map +1 -1
  85. package/dist/leader-thread/recreate-db.d.ts +2 -2
  86. package/dist/leader-thread/recreate-db.d.ts.map +1 -1
  87. package/dist/leader-thread/recreate-db.js +6 -6
  88. package/dist/leader-thread/recreate-db.js.map +1 -1
  89. package/dist/leader-thread/shutdown-channel.d.ts +2 -2
  90. package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
  91. package/dist/leader-thread/shutdown-channel.js +2 -2
  92. package/dist/leader-thread/shutdown-channel.js.map +1 -1
  93. package/dist/leader-thread/stream-events.d.ts +56 -0
  94. package/dist/leader-thread/stream-events.d.ts.map +1 -0
  95. package/dist/leader-thread/stream-events.js +167 -0
  96. package/dist/leader-thread/stream-events.js.map +1 -0
  97. package/dist/leader-thread/types.d.ts +95 -17
  98. package/dist/leader-thread/types.d.ts.map +1 -1
  99. package/dist/leader-thread/types.js +13 -0
  100. package/dist/leader-thread/types.js.map +1 -1
  101. package/dist/logging.d.ts +40 -0
  102. package/dist/logging.d.ts.map +1 -0
  103. package/dist/logging.js +33 -0
  104. package/dist/logging.js.map +1 -0
  105. package/dist/make-client-session.d.ts +5 -3
  106. package/dist/make-client-session.d.ts.map +1 -1
  107. package/dist/make-client-session.js +7 -4
  108. package/dist/make-client-session.js.map +1 -1
  109. package/dist/materializer-helper.d.ts +6 -6
  110. package/dist/materializer-helper.d.ts.map +1 -1
  111. package/dist/materializer-helper.js +18 -8
  112. package/dist/materializer-helper.js.map +1 -1
  113. package/dist/otel.d.ts +2 -1
  114. package/dist/otel.d.ts.map +1 -1
  115. package/dist/otel.js +7 -2
  116. package/dist/otel.js.map +1 -1
  117. package/dist/rematerialize-from-eventlog.d.ts +3 -3
  118. package/dist/rematerialize-from-eventlog.d.ts.map +1 -1
  119. package/dist/rematerialize-from-eventlog.js +40 -29
  120. package/dist/rematerialize-from-eventlog.js.map +1 -1
  121. package/dist/schema/EventDef/define.d.ts +161 -0
  122. package/dist/schema/EventDef/define.d.ts.map +1 -0
  123. package/dist/schema/EventDef/define.js +140 -0
  124. package/dist/schema/EventDef/define.js.map +1 -0
  125. package/dist/schema/EventDef/deprecated.d.ts +99 -0
  126. package/dist/schema/EventDef/deprecated.d.ts.map +1 -0
  127. package/dist/schema/EventDef/deprecated.js +144 -0
  128. package/dist/schema/EventDef/deprecated.js.map +1 -0
  129. package/dist/schema/EventDef/deprecated.test.d.ts +2 -0
  130. package/dist/schema/EventDef/deprecated.test.d.ts.map +1 -0
  131. package/dist/schema/EventDef/deprecated.test.js +95 -0
  132. package/dist/schema/EventDef/deprecated.test.js.map +1 -0
  133. package/dist/schema/EventDef/event-def.d.ts +110 -0
  134. package/dist/schema/EventDef/event-def.d.ts.map +1 -0
  135. package/dist/schema/EventDef/event-def.js +2 -0
  136. package/dist/schema/EventDef/event-def.js.map +1 -0
  137. package/dist/schema/EventDef/facts.d.ts +118 -0
  138. package/dist/schema/EventDef/facts.d.ts.map +1 -0
  139. package/dist/schema/EventDef/facts.js +53 -0
  140. package/dist/schema/EventDef/facts.js.map +1 -0
  141. package/dist/schema/EventDef/materializer.d.ts +155 -0
  142. package/dist/schema/EventDef/materializer.d.ts.map +1 -0
  143. package/dist/schema/EventDef/materializer.js +83 -0
  144. package/dist/schema/EventDef/materializer.js.map +1 -0
  145. package/dist/schema/EventDef/mod.d.ts +6 -0
  146. package/dist/schema/EventDef/mod.d.ts.map +1 -0
  147. package/dist/schema/EventDef/mod.js +6 -0
  148. package/dist/schema/EventDef/mod.js.map +1 -0
  149. package/dist/schema/EventSequenceNumber/client.d.ts +136 -0
  150. package/dist/schema/EventSequenceNumber/client.d.ts.map +1 -0
  151. package/dist/schema/EventSequenceNumber/client.js +193 -0
  152. package/dist/schema/EventSequenceNumber/client.js.map +1 -0
  153. package/dist/schema/EventSequenceNumber/global.d.ts +15 -0
  154. package/dist/schema/EventSequenceNumber/global.d.ts.map +1 -0
  155. package/dist/schema/EventSequenceNumber/global.js +14 -0
  156. package/dist/schema/EventSequenceNumber/global.js.map +1 -0
  157. package/dist/schema/EventSequenceNumber/mod.d.ts +37 -0
  158. package/dist/schema/EventSequenceNumber/mod.d.ts.map +1 -0
  159. package/dist/schema/EventSequenceNumber/mod.js +37 -0
  160. package/dist/schema/EventSequenceNumber/mod.js.map +1 -0
  161. package/dist/schema/EventSequenceNumber.test.js +44 -44
  162. package/dist/schema/EventSequenceNumber.test.js.map +1 -1
  163. package/dist/schema/{LiveStoreEvent.d.ts → LiveStoreEvent/client.d.ts} +102 -111
  164. package/dist/schema/LiveStoreEvent/client.d.ts.map +1 -0
  165. package/dist/schema/LiveStoreEvent/client.js +176 -0
  166. package/dist/schema/LiveStoreEvent/client.js.map +1 -0
  167. package/dist/schema/LiveStoreEvent/client.test.d.ts +2 -0
  168. package/dist/schema/LiveStoreEvent/client.test.d.ts.map +1 -0
  169. package/dist/schema/LiveStoreEvent/client.test.js +111 -0
  170. package/dist/schema/LiveStoreEvent/client.test.js.map +1 -0
  171. package/dist/schema/LiveStoreEvent/for-event-def.d.ts +52 -0
  172. package/dist/schema/LiveStoreEvent/for-event-def.d.ts.map +1 -0
  173. package/dist/schema/LiveStoreEvent/for-event-def.js +2 -0
  174. package/dist/schema/LiveStoreEvent/for-event-def.js.map +1 -0
  175. package/dist/schema/LiveStoreEvent/global.d.ts +36 -0
  176. package/dist/schema/LiveStoreEvent/global.d.ts.map +1 -0
  177. package/dist/schema/LiveStoreEvent/global.js +31 -0
  178. package/dist/schema/LiveStoreEvent/global.js.map +1 -0
  179. package/dist/schema/LiveStoreEvent/input.d.ts +46 -0
  180. package/dist/schema/LiveStoreEvent/input.d.ts.map +1 -0
  181. package/dist/schema/LiveStoreEvent/input.js +26 -0
  182. package/dist/schema/LiveStoreEvent/input.js.map +1 -0
  183. package/dist/schema/LiveStoreEvent/mod.d.ts +5 -0
  184. package/dist/schema/LiveStoreEvent/mod.d.ts.map +1 -0
  185. package/dist/schema/LiveStoreEvent/mod.js +5 -0
  186. package/dist/schema/LiveStoreEvent/mod.js.map +1 -0
  187. package/dist/schema/events.d.ts +1 -1
  188. package/dist/schema/events.d.ts.map +1 -1
  189. package/dist/schema/events.js +1 -1
  190. package/dist/schema/events.js.map +1 -1
  191. package/dist/schema/mod.d.ts +6 -4
  192. package/dist/schema/mod.d.ts.map +1 -1
  193. package/dist/schema/mod.js +5 -4
  194. package/dist/schema/mod.js.map +1 -1
  195. package/dist/schema/schema.d.ts +16 -1
  196. package/dist/schema/schema.d.ts.map +1 -1
  197. package/dist/schema/schema.js +32 -4
  198. package/dist/schema/schema.js.map +1 -1
  199. package/dist/schema/state/sqlite/client-document-def.d.ts +2 -1
  200. package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -1
  201. package/dist/schema/state/sqlite/client-document-def.js +36 -15
  202. package/dist/schema/state/sqlite/client-document-def.js.map +1 -1
  203. package/dist/schema/state/sqlite/client-document-def.test.js +121 -2
  204. package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -1
  205. package/dist/schema/state/sqlite/column-annotations.d.ts.map +1 -1
  206. package/dist/schema/state/sqlite/column-annotations.js +1 -1
  207. package/dist/schema/state/sqlite/column-annotations.js.map +1 -1
  208. package/dist/schema/state/sqlite/column-annotations.test.js +2 -2
  209. package/dist/schema/state/sqlite/column-annotations.test.js.map +1 -1
  210. package/dist/schema/state/sqlite/column-def.d.ts.map +1 -1
  211. package/dist/schema/state/sqlite/column-def.js +96 -47
  212. package/dist/schema/state/sqlite/column-def.js.map +1 -1
  213. package/dist/schema/state/sqlite/column-def.test.js +51 -12
  214. package/dist/schema/state/sqlite/column-def.test.js.map +1 -1
  215. package/dist/schema/state/sqlite/column-spec.d.ts.map +1 -1
  216. package/dist/schema/state/sqlite/column-spec.js +30 -12
  217. package/dist/schema/state/sqlite/column-spec.js.map +1 -1
  218. package/dist/schema/state/sqlite/column-spec.test.js +24 -15
  219. package/dist/schema/state/sqlite/column-spec.test.js.map +1 -1
  220. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js +2 -2
  221. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js.map +1 -1
  222. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts +16 -10
  223. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts.map +1 -1
  224. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js +15 -4
  225. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js.map +1 -1
  226. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js +1 -1
  227. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js.map +1 -1
  228. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts +1 -1
  229. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts.map +1 -1
  230. package/dist/schema/state/sqlite/db-schema/dsl/mod.js +1 -1
  231. package/dist/schema/state/sqlite/db-schema/dsl/mod.js.map +1 -1
  232. package/dist/schema/state/sqlite/mod.d.ts +2 -2
  233. package/dist/schema/state/sqlite/mod.d.ts.map +1 -1
  234. package/dist/schema/state/sqlite/mod.js +5 -7
  235. package/dist/schema/state/sqlite/mod.js.map +1 -1
  236. package/dist/schema/state/sqlite/query-builder/api.d.ts +51 -22
  237. package/dist/schema/state/sqlite/query-builder/api.d.ts.map +1 -1
  238. package/dist/schema/state/sqlite/query-builder/astToSql.d.ts.map +1 -1
  239. package/dist/schema/state/sqlite/query-builder/astToSql.js +99 -22
  240. package/dist/schema/state/sqlite/query-builder/astToSql.js.map +1 -1
  241. package/dist/schema/state/sqlite/query-builder/impl.d.ts +1 -1
  242. package/dist/schema/state/sqlite/query-builder/impl.d.ts.map +1 -1
  243. package/dist/schema/state/sqlite/query-builder/impl.js +28 -15
  244. package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -1
  245. package/dist/schema/state/sqlite/query-builder/impl.test.js +231 -93
  246. package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -1
  247. package/dist/schema/state/sqlite/schema-helpers.d.ts +2 -2
  248. package/dist/schema/state/sqlite/schema-helpers.d.ts.map +1 -1
  249. package/dist/schema/state/sqlite/schema-helpers.js +24 -14
  250. package/dist/schema/state/sqlite/schema-helpers.js.map +1 -1
  251. package/dist/schema/state/sqlite/schema-helpers.test.d.ts +2 -0
  252. package/dist/schema/state/sqlite/schema-helpers.test.d.ts.map +1 -0
  253. package/dist/schema/state/sqlite/schema-helpers.test.js +36 -0
  254. package/dist/schema/state/sqlite/schema-helpers.test.js.map +1 -0
  255. package/dist/schema/state/sqlite/{system-tables.d.ts → system-tables/eventlog-tables.d.ts} +21 -450
  256. package/dist/schema/state/sqlite/system-tables/eventlog-tables.d.ts.map +1 -0
  257. package/dist/schema/state/sqlite/system-tables/eventlog-tables.js +54 -0
  258. package/dist/schema/state/sqlite/system-tables/eventlog-tables.js.map +1 -0
  259. package/dist/schema/state/sqlite/system-tables/mod.d.ts +3 -0
  260. package/dist/schema/state/sqlite/system-tables/mod.d.ts.map +1 -0
  261. package/dist/schema/state/sqlite/system-tables/mod.js +3 -0
  262. package/dist/schema/state/sqlite/system-tables/mod.js.map +1 -0
  263. package/dist/schema/state/sqlite/system-tables/state-tables.d.ts +456 -0
  264. package/dist/schema/state/sqlite/system-tables/state-tables.d.ts.map +1 -0
  265. package/dist/schema/state/sqlite/system-tables/state-tables.js +55 -0
  266. package/dist/schema/state/sqlite/system-tables/state-tables.js.map +1 -0
  267. package/dist/schema/state/sqlite/table-def.d.ts +5 -3
  268. package/dist/schema/state/sqlite/table-def.d.ts.map +1 -1
  269. package/dist/schema/state/sqlite/table-def.js +1 -1
  270. package/dist/schema/state/sqlite/table-def.js.map +1 -1
  271. package/dist/schema/state/sqlite/table-def.test.js +92 -3
  272. package/dist/schema/state/sqlite/table-def.test.js.map +1 -1
  273. package/dist/schema/unknown-events.d.ts +47 -0
  274. package/dist/schema/unknown-events.d.ts.map +1 -0
  275. package/dist/schema/unknown-events.js +69 -0
  276. package/dist/schema/unknown-events.js.map +1 -0
  277. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.d.ts +2 -0
  278. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.d.ts.map +1 -0
  279. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js +73 -0
  280. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js.map +1 -0
  281. package/dist/schema-management/common.js +2 -2
  282. package/dist/schema-management/common.js.map +1 -1
  283. package/dist/schema-management/migrations.d.ts +32 -2
  284. package/dist/schema-management/migrations.d.ts.map +1 -1
  285. package/dist/schema-management/migrations.js +38 -6
  286. package/dist/schema-management/migrations.js.map +1 -1
  287. package/dist/schema-management/validate-schema.d.ts +3 -3
  288. package/dist/schema-management/validate-schema.d.ts.map +1 -1
  289. package/dist/schema-management/validate-schema.js +2 -2
  290. package/dist/schema-management/validate-schema.js.map +1 -1
  291. package/dist/sql-queries/sql-queries.d.ts.map +1 -1
  292. package/dist/sql-queries/sql-queries.js +18 -6
  293. package/dist/sql-queries/sql-queries.js.map +1 -1
  294. package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
  295. package/dist/sql-queries/sql-query-builder.js.map +1 -1
  296. package/dist/sqlite-db-helper.js +3 -3
  297. package/dist/sqlite-db-helper.js.map +1 -1
  298. package/dist/sqlite-types.d.ts +5 -5
  299. package/dist/sqlite-types.d.ts.map +1 -1
  300. package/dist/sqlite-types.js.map +1 -1
  301. package/dist/sync/ClientSessionSyncProcessor.d.ts +12 -12
  302. package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
  303. package/dist/sync/ClientSessionSyncProcessor.js +99 -114
  304. package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
  305. package/dist/sync/errors.d.ts +0 -33
  306. package/dist/sync/errors.d.ts.map +1 -1
  307. package/dist/sync/errors.js +5 -22
  308. package/dist/sync/errors.js.map +1 -1
  309. package/dist/sync/index.d.ts +2 -0
  310. package/dist/sync/index.d.ts.map +1 -1
  311. package/dist/sync/index.js +2 -0
  312. package/dist/sync/index.js.map +1 -1
  313. package/dist/sync/mock-sync-backend.d.ts +10 -8
  314. package/dist/sync/mock-sync-backend.d.ts.map +1 -1
  315. package/dist/sync/mock-sync-backend.js +71 -69
  316. package/dist/sync/mock-sync-backend.js.map +1 -1
  317. package/dist/sync/next/compact-events.d.ts.map +1 -1
  318. package/dist/sync/next/compact-events.js +11 -12
  319. package/dist/sync/next/compact-events.js.map +1 -1
  320. package/dist/sync/next/facts.d.ts +5 -5
  321. package/dist/sync/next/facts.d.ts.map +1 -1
  322. package/dist/sync/next/facts.js +7 -8
  323. package/dist/sync/next/facts.js.map +1 -1
  324. package/dist/sync/next/history-dag-common.d.ts +54 -15
  325. package/dist/sync/next/history-dag-common.d.ts.map +1 -1
  326. package/dist/sync/next/history-dag-common.js +198 -9
  327. package/dist/sync/next/history-dag-common.js.map +1 -1
  328. package/dist/sync/next/history-dag.d.ts.map +1 -1
  329. package/dist/sync/next/history-dag.js +11 -11
  330. package/dist/sync/next/history-dag.js.map +1 -1
  331. package/dist/sync/next/rebase-events.d.ts +5 -5
  332. package/dist/sync/next/rebase-events.d.ts.map +1 -1
  333. package/dist/sync/next/rebase-events.js +6 -6
  334. package/dist/sync/next/rebase-events.js.map +1 -1
  335. package/dist/sync/next/test/compact-events.calculator.test.js +2 -2
  336. package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
  337. package/dist/sync/next/test/compact-events.test.d.ts.map +1 -1
  338. package/dist/sync/next/test/compact-events.test.js +2 -2
  339. package/dist/sync/next/test/compact-events.test.js.map +1 -1
  340. package/dist/sync/next/test/event-fixtures.d.ts +2 -2
  341. package/dist/sync/next/test/event-fixtures.d.ts.map +1 -1
  342. package/dist/sync/next/test/event-fixtures.js +11 -11
  343. package/dist/sync/next/test/event-fixtures.js.map +1 -1
  344. package/dist/sync/sync-backend-kv.d.ts +3 -3
  345. package/dist/sync/sync-backend-kv.d.ts.map +1 -1
  346. package/dist/sync/sync-backend-kv.js +3 -3
  347. package/dist/sync/sync-backend-kv.js.map +1 -1
  348. package/dist/sync/sync-backend.d.ts +33 -13
  349. package/dist/sync/sync-backend.d.ts.map +1 -1
  350. package/dist/sync/sync-backend.js +38 -1
  351. package/dist/sync/sync-backend.js.map +1 -1
  352. package/dist/sync/sync.d.ts +23 -2
  353. package/dist/sync/sync.d.ts.map +1 -1
  354. package/dist/sync/syncstate.d.ts +55 -55
  355. package/dist/sync/syncstate.d.ts.map +1 -1
  356. package/dist/sync/syncstate.js +80 -98
  357. package/dist/sync/syncstate.js.map +1 -1
  358. package/dist/sync/syncstate.test.js +221 -132
  359. package/dist/sync/syncstate.test.js.map +1 -1
  360. package/dist/sync/transport-chunking.d.ts +36 -0
  361. package/dist/sync/transport-chunking.d.ts.map +1 -0
  362. package/dist/sync/transport-chunking.js +56 -0
  363. package/dist/sync/transport-chunking.js.map +1 -0
  364. package/dist/sync/validate-push-payload.d.ts +2 -2
  365. package/dist/sync/validate-push-payload.d.ts.map +1 -1
  366. package/dist/sync/validate-push-payload.js +4 -6
  367. package/dist/sync/validate-push-payload.js.map +1 -1
  368. package/dist/testing/event-factory.d.ts +68 -0
  369. package/dist/testing/event-factory.d.ts.map +1 -0
  370. package/dist/testing/event-factory.js +78 -0
  371. package/dist/testing/event-factory.js.map +1 -0
  372. package/dist/testing/mod.d.ts +2 -0
  373. package/dist/testing/mod.d.ts.map +1 -0
  374. package/dist/testing/mod.js +2 -0
  375. package/dist/testing/mod.js.map +1 -0
  376. package/dist/util.js +2 -2
  377. package/dist/util.js.map +1 -1
  378. package/dist/version.d.ts +24 -5
  379. package/dist/version.d.ts.map +1 -1
  380. package/dist/version.js +25 -8
  381. package/dist/version.js.map +1 -1
  382. package/package.json +69 -16
  383. package/src/ClientSessionLeaderThreadProxy.ts +27 -12
  384. package/src/WorkerTransportError.ts +12 -0
  385. package/src/adapter-types.ts +50 -7
  386. package/src/bounded-collections.ts +6 -5
  387. package/src/debug-info.ts +37 -6
  388. package/src/devtools/devtools-compatibility.test.ts +18 -0
  389. package/src/devtools/devtools-messages-client-session.ts +22 -4
  390. package/src/devtools/devtools-messages-common.ts +7 -12
  391. package/src/devtools/devtools-messages-leader.ts +29 -10
  392. package/src/devtools/devtools-sessioninfo.ts +8 -5
  393. package/src/devtools/mod.ts +11 -2
  394. package/src/errors.ts +32 -24
  395. package/src/index.ts +4 -1
  396. package/src/leader-thread/LeaderSyncProcessor.ts +523 -373
  397. package/src/leader-thread/RejectedPushError.ts +106 -0
  398. package/src/leader-thread/connection.ts +1 -1
  399. package/src/leader-thread/eventlog.ts +112 -39
  400. package/src/leader-thread/leader-worker-devtools.ts +201 -120
  401. package/src/leader-thread/make-leader-thread-layer.test.ts +44 -0
  402. package/src/leader-thread/make-leader-thread-layer.ts +125 -40
  403. package/src/leader-thread/materialize-event.ts +40 -10
  404. package/src/leader-thread/mod.ts +1 -0
  405. package/src/leader-thread/recreate-db.ts +7 -7
  406. package/src/leader-thread/shutdown-channel.ts +4 -8
  407. package/src/leader-thread/stream-events.ts +206 -0
  408. package/src/leader-thread/types.ts +68 -18
  409. package/src/logging.ts +62 -0
  410. package/src/make-client-session.ts +11 -5
  411. package/src/materializer-helper.ts +27 -16
  412. package/src/otel.ts +13 -2
  413. package/src/rematerialize-from-eventlog.ts +61 -51
  414. package/src/schema/EventDef/define.ts +217 -0
  415. package/src/schema/EventDef/deprecated.test.ts +129 -0
  416. package/src/schema/EventDef/deprecated.ts +175 -0
  417. package/src/schema/EventDef/event-def.ts +125 -0
  418. package/src/schema/EventDef/facts.ts +135 -0
  419. package/src/schema/EventDef/materializer.ts +172 -0
  420. package/src/schema/EventDef/mod.ts +5 -0
  421. package/src/schema/EventSequenceNumber/client.ts +257 -0
  422. package/src/schema/EventSequenceNumber/global.ts +19 -0
  423. package/src/schema/EventSequenceNumber/mod.ts +37 -0
  424. package/src/schema/EventSequenceNumber.test.ts +72 -53
  425. package/src/schema/LiveStoreEvent/client.test.ts +129 -0
  426. package/src/schema/LiveStoreEvent/client.ts +235 -0
  427. package/src/schema/LiveStoreEvent/for-event-def.ts +60 -0
  428. package/src/schema/LiveStoreEvent/global.ts +45 -0
  429. package/src/schema/LiveStoreEvent/input.ts +63 -0
  430. package/src/schema/LiveStoreEvent/mod.ts +4 -0
  431. package/src/schema/events.ts +1 -1
  432. package/src/schema/mod.ts +6 -4
  433. package/src/schema/schema.ts +46 -5
  434. package/src/schema/state/sqlite/client-document-def.test.ts +144 -5
  435. package/src/schema/state/sqlite/client-document-def.ts +47 -34
  436. package/src/schema/state/sqlite/column-annotations.test.ts +3 -2
  437. package/src/schema/state/sqlite/column-annotations.ts +2 -1
  438. package/src/schema/state/sqlite/column-def.test.ts +66 -12
  439. package/src/schema/state/sqlite/column-def.ts +119 -47
  440. package/src/schema/state/sqlite/column-spec.test.ts +32 -17
  441. package/src/schema/state/sqlite/column-spec.ts +37 -11
  442. package/src/schema/state/sqlite/db-schema/ast/sqlite.ts +2 -2
  443. package/src/schema/state/sqlite/db-schema/dsl/field-defs.test.ts +2 -1
  444. package/src/schema/state/sqlite/db-schema/dsl/field-defs.ts +41 -15
  445. package/src/schema/state/sqlite/db-schema/dsl/mod.ts +13 -19
  446. package/src/schema/state/sqlite/mod.ts +7 -8
  447. package/src/schema/state/sqlite/query-builder/api.ts +55 -17
  448. package/src/schema/state/sqlite/query-builder/astToSql.ts +110 -21
  449. package/src/schema/state/sqlite/query-builder/impl.test.ts +267 -93
  450. package/src/schema/state/sqlite/query-builder/impl.ts +26 -13
  451. package/src/schema/state/sqlite/schema-helpers.test.ts +44 -0
  452. package/src/schema/state/sqlite/schema-helpers.ts +30 -22
  453. package/src/schema/state/sqlite/system-tables/eventlog-tables.ts +64 -0
  454. package/src/schema/state/sqlite/system-tables/mod.ts +2 -0
  455. package/src/schema/state/sqlite/system-tables/state-tables.ts +69 -0
  456. package/src/schema/state/sqlite/table-def.test.ts +114 -3
  457. package/src/schema/state/sqlite/table-def.ts +16 -22
  458. package/src/schema/unknown-events.ts +131 -0
  459. package/src/schema-management/__tests__/migrations-autoincrement-quoting.test.ts +88 -0
  460. package/src/schema-management/common.ts +2 -2
  461. package/src/schema-management/migrations.ts +42 -9
  462. package/src/schema-management/validate-schema.ts +3 -3
  463. package/src/sql-queries/sql-queries.ts +18 -6
  464. package/src/sql-queries/sql-query-builder.ts +1 -0
  465. package/src/sqlite-db-helper.ts +3 -3
  466. package/src/sqlite-types.ts +6 -5
  467. package/src/sync/ClientSessionSyncProcessor.ts +152 -142
  468. package/src/sync/errors.ts +12 -24
  469. package/src/sync/index.ts +2 -0
  470. package/src/sync/mock-sync-backend.ts +146 -104
  471. package/src/sync/next/compact-events.ts +10 -11
  472. package/src/sync/next/facts.ts +13 -14
  473. package/src/sync/next/history-dag-common.ts +280 -26
  474. package/src/sync/next/history-dag.ts +17 -13
  475. package/src/sync/next/rebase-events.ts +12 -12
  476. package/src/sync/next/test/compact-events.calculator.test.ts +3 -2
  477. package/src/sync/next/test/compact-events.test.ts +4 -3
  478. package/src/sync/next/test/event-fixtures.ts +13 -13
  479. package/src/sync/sync-backend-kv.ts +4 -3
  480. package/src/sync/sync-backend.ts +66 -17
  481. package/src/sync/sync.ts +24 -2
  482. package/src/sync/syncstate.test.ts +583 -419
  483. package/src/sync/syncstate.ts +127 -122
  484. package/src/sync/transport-chunking.ts +90 -0
  485. package/src/sync/validate-push-payload.ts +6 -8
  486. package/src/testing/event-factory.ts +131 -0
  487. package/src/testing/mod.ts +1 -0
  488. package/src/util.ts +2 -2
  489. package/src/version.ts +33 -8
  490. package/dist/schema/EventDef.d.ts +0 -126
  491. package/dist/schema/EventDef.d.ts.map +0 -1
  492. package/dist/schema/EventDef.js +0 -46
  493. package/dist/schema/EventDef.js.map +0 -1
  494. package/dist/schema/EventSequenceNumber.d.ts +0 -80
  495. package/dist/schema/EventSequenceNumber.d.ts.map +0 -1
  496. package/dist/schema/EventSequenceNumber.js +0 -139
  497. package/dist/schema/EventSequenceNumber.js.map +0 -1
  498. package/dist/schema/LiveStoreEvent.d.ts.map +0 -1
  499. package/dist/schema/LiveStoreEvent.js +0 -147
  500. package/dist/schema/LiveStoreEvent.js.map +0 -1
  501. package/dist/schema/state/sqlite/system-tables.d.ts.map +0 -1
  502. package/dist/schema/state/sqlite/system-tables.js +0 -81
  503. package/dist/schema/state/sqlite/system-tables.js.map +0 -1
  504. package/dist/sync/next/graphology.d.ts +0 -8
  505. package/dist/sync/next/graphology.d.ts.map +0 -1
  506. package/dist/sync/next/graphology.js +0 -30
  507. package/dist/sync/next/graphology.js.map +0 -1
  508. package/dist/sync/next/graphology_.d.ts +0 -3
  509. package/dist/sync/next/graphology_.d.ts.map +0 -1
  510. package/dist/sync/next/graphology_.js +0 -3
  511. package/dist/sync/next/graphology_.js.map +0 -1
  512. package/src/schema/EventDef.ts +0 -222
  513. package/src/schema/EventSequenceNumber.ts +0 -199
  514. package/src/schema/LiveStoreEvent.ts +0 -286
  515. package/src/schema/state/sqlite/system-tables.ts +0 -106
  516. package/src/sync/next/ambient.d.ts +0 -3
  517. package/src/sync/next/graphology.ts +0 -41
  518. package/src/sync/next/graphology_.ts +0 -2
@@ -0,0 +1,45 @@
1
+ import { Schema } from '@livestore/utils/effect'
2
+
3
+ import * as EventSequenceNumber from '../EventSequenceNumber/mod.ts'
4
+
5
+ /**
6
+ * Effect Schema for global events with integer sequence numbers.
7
+ * @example
8
+ * ```ts
9
+ * const event: LiveStoreEvent.Global.Encoded = {
10
+ * name: 'todoCreated-v1',
11
+ * args: { id: 'abc', text: 'Buy milk' },
12
+ * seqNum: 5, // This event's position in the global log
13
+ * parentSeqNum: 4, // Points to the previous event
14
+ * clientId: 'client-xyz',
15
+ * sessionId: 'session-123'
16
+ * }
17
+ * ```
18
+ */
19
+ export const Encoded = Schema.Struct({
20
+ name: Schema.String,
21
+ args: Schema.Any,
22
+ seqNum: EventSequenceNumber.Global.Schema,
23
+ parentSeqNum: EventSequenceNumber.Global.Schema,
24
+ clientId: Schema.String,
25
+ sessionId: Schema.String,
26
+ }).annotations({ title: 'LiveStoreEvent.Global.Encoded' })
27
+
28
+ /** Event with integer sequence numbers for sync backend wire format. */
29
+ export type Encoded = typeof Encoded.Type
30
+
31
+ /** Converts a Global event to Client format by expanding integer seqNums to composite form. */
32
+ export const toClientEncoded = (
33
+ event: Encoded,
34
+ ): {
35
+ name: string
36
+ args: any
37
+ seqNum: EventSequenceNumber.Client.Composite
38
+ parentSeqNum: EventSequenceNumber.Client.Composite
39
+ clientId: string
40
+ sessionId: string
41
+ } => ({
42
+ ...event,
43
+ seqNum: EventSequenceNumber.Client.fromGlobal(event.seqNum),
44
+ parentSeqNum: EventSequenceNumber.Client.fromGlobal(event.parentSeqNum),
45
+ })
@@ -0,0 +1,63 @@
1
+ import { Schema } from '@livestore/utils/effect'
2
+
3
+ import type { EventDef, EventDefRecord } from '../EventDef/mod.ts'
4
+ import type { LiveStoreSchema } from '../schema.ts'
5
+ import type * as ForEventDef from './for-event-def.ts'
6
+
7
+ /**
8
+ * Effect Schema for validating/decoding input events with encoded args.
9
+ * @example
10
+ * ```ts
11
+ * import { Schema } from '@effect/schema'
12
+ * const decoded = Schema.decodeUnknownSync(LiveStoreEvent.Input.Encoded)(rawEvent)
13
+ * ```
14
+ */
15
+ export const Encoded = Schema.Struct({
16
+ name: Schema.String,
17
+ args: Schema.Any,
18
+ }).annotations({ title: 'LiveStoreEvent.Input.Encoded' })
19
+
20
+ /** Event without sequence numbers, with decoded (native TypeScript) args. */
21
+ export type Decoded = ForEventDef.InputDecoded<EventDef.Any>
22
+
23
+ /** Event without sequence numbers, with encoded (serialized) args. */
24
+ export type Encoded = ForEventDef.InputEncoded<EventDef.Any>
25
+
26
+ /** Union of all input event types for a given schema (type-safe event discrimination). */
27
+ export type ForSchema<TSchema extends LiveStoreSchema> = {
28
+ [K in keyof TSchema['_EventDefMapType']]: ForEventDef.InputDecoded<TSchema['_EventDefMapType'][K]>
29
+ }[keyof TSchema['_EventDefMapType']]
30
+
31
+ /** Effect Schema union of all event types in an EventDefRecord (input format, no sequence numbers). */
32
+ export type ForRecord<TEventDefRecord extends EventDefRecord> = Schema.Schema<
33
+ {
34
+ [K in keyof TEventDefRecord]: {
35
+ name: K
36
+ args: Schema.Schema.Type<TEventDefRecord[K]['schema']>
37
+ }
38
+ }[keyof TEventDefRecord],
39
+ {
40
+ [K in keyof TEventDefRecord]: {
41
+ name: K
42
+ args: Schema.Schema.Encoded<TEventDefRecord[K]['schema']>
43
+ }
44
+ }[keyof TEventDefRecord]
45
+ >
46
+
47
+ /**
48
+ * Creates an Effect Schema union for all event types in a schema (input format, no sequence numbers).
49
+ * @example
50
+ * ```ts
51
+ * const inputSchema = LiveStoreEvent.Input.makeSchema(schema)
52
+ * const event = Schema.decodeUnknownSync(inputSchema)(rawEvent)
53
+ * ```
54
+ */
55
+ export const makeSchema = <TSchema extends LiveStoreSchema>(schema: TSchema): ForRecord<TSchema['_EventDefMapType']> =>
56
+ Schema.Union(
57
+ ...[...schema.eventsDefsMap.values()].map((def) =>
58
+ Schema.Struct({
59
+ name: Schema.Literal(def.name),
60
+ args: def.schema,
61
+ }),
62
+ ),
63
+ ).annotations({ title: 'LiveStoreEvent.Input' }) as any
@@ -0,0 +1,4 @@
1
+ export * as Client from './client.ts'
2
+ export * as ForEventDef from './for-event-def.ts'
3
+ export * as Global from './global.ts'
4
+ export * as Input from './input.ts'
@@ -1 +1 @@
1
- export { clientOnly, defineEvent, synced } from './EventDef.ts'
1
+ export { clientOnly, defineEvent, synced } from './EventDef/mod.ts'
package/src/schema/mod.ts CHANGED
@@ -1,9 +1,11 @@
1
- export * from './EventDef.ts'
2
- export * as EventSequenceNumber from './EventSequenceNumber.ts'
1
+ export * from './EventDef/mod.ts'
2
+ export * as EventSequenceNumber from './EventSequenceNumber/mod.ts'
3
3
  export * as Events from './events.ts'
4
- export * as LiveStoreEvent from './LiveStoreEvent.ts'
4
+ export * as LiveStoreEvent from './LiveStoreEvent/mod.ts'
5
5
  export * from './schema.ts'
6
6
  export * as State from './state/mod.ts'
7
7
  export { SqliteAst, SqliteDsl } from './state/sqlite/db-schema/mod.ts'
8
8
  export * from './state/sqlite/schema-helpers.ts'
9
- export * as SystemTables from './state/sqlite/system-tables.ts'
9
+ export * as SystemTables from './state/sqlite/system-tables/mod.ts'
10
+ export type { UnknownEvents } from './unknown-events.ts'
11
+ export { normalizeUnknownEventHandling, resolveEventDef } from './unknown-events.ts'
@@ -1,15 +1,19 @@
1
1
  import { isReadonlyArray, shouldNeverHappen } from '@livestore/utils'
2
2
 
3
3
  import type { MigrationOptions } from '../adapter-types.ts'
4
- import type { EventDef, EventDefRecord, Materializer } from './EventDef.ts'
4
+ import type { EventDef, EventDefRecord, Materializer } from './EventDef/mod.ts'
5
5
  import { tableIsClientDocumentTable } from './state/sqlite/client-document-def.ts'
6
6
  import type { SqliteDsl } from './state/sqlite/db-schema/mod.ts'
7
- import { stateSystemTables } from './state/sqlite/system-tables.ts'
7
+ import { stateSystemTables } from './state/sqlite/system-tables/state-tables.ts'
8
8
  import type { TableDef } from './state/sqlite/table-def.ts'
9
+ import type { UnknownEvents } from './unknown-events.ts'
10
+ import { normalizeUnknownEventHandling } from './unknown-events.ts'
9
11
 
10
12
  export const LiveStoreSchemaSymbol = Symbol.for('livestore.LiveStoreSchema')
11
13
  export type LiveStoreSchemaSymbol = typeof LiveStoreSchemaSymbol
12
14
 
15
+ export const UNKNOWN_EVENT_SCHEMA_HASH = -1
16
+
13
17
  export interface LiveStoreSchema<
14
18
  TDbSchema extends SqliteDsl.DbSchema = SqliteDsl.DbSchema,
15
19
  TEventsDefRecord extends EventDefRecord = EventDefRecord,
@@ -22,6 +26,7 @@ export interface LiveStoreSchema<
22
26
 
23
27
  readonly state: InternalState
24
28
  readonly eventsDefsMap: Map<string, EventDef.AnyWithoutFn>
29
+ readonly unknownEventHandling: UnknownEvents.HandlingConfig
25
30
  readonly devtools: {
26
31
  /** @default 'default' */
27
32
  readonly alias: string
@@ -32,6 +37,35 @@ export namespace LiveStoreSchema {
32
37
  export type Any = LiveStoreSchema<any, any>
33
38
  }
34
39
 
40
+ /**
41
+ * Runtime type guard for LiveStoreSchema.
42
+ *
43
+ * The guard intentionally performs lightweight structural checks that are
44
+ * stable across implementations. It verifies the identifying symbol marker
45
+ * and the presence of core maps/state used at runtime.
46
+ */
47
+ export const isLiveStoreSchema = (value: unknown): value is LiveStoreSchema<any, any> => {
48
+ if (typeof value !== 'object' || value === null) return false
49
+
50
+ const v: any = value
51
+
52
+ // Identity marker must match exactly
53
+ if (v.LiveStoreSchemaSymbol !== LiveStoreSchemaSymbol) return false
54
+
55
+ // Core structures used at runtime
56
+ const hasEventsMap = v.eventsDefsMap instanceof Map
57
+ const hasStateSqliteTables = v.state?.sqlite?.tables instanceof Map
58
+ const hasStateMaterializers = v.state?.materializers instanceof Map
59
+ const hasDevtoolsAlias = typeof v.devtools?.alias === 'string'
60
+
61
+ return (
62
+ hasEventsMap === true &&
63
+ hasStateSqliteTables === true &&
64
+ hasStateMaterializers === true &&
65
+ hasDevtoolsAlias === true
66
+ )
67
+ }
68
+
35
69
  // TODO abstract this further away from sqlite/tables
36
70
  export interface InternalState {
37
71
  readonly sqlite: {
@@ -55,6 +89,10 @@ export interface InputSchema {
55
89
  */
56
90
  readonly alias?: string
57
91
  }
92
+ /**
93
+ * Configures how unknown events should be handled. Defaults to `{ strategy: 'warn' }`.
94
+ */
95
+ readonly unknownEventHandling?: UnknownEvents.HandlingConfig
58
96
  }
59
97
 
60
98
  export const makeSchema = <TInputSchema extends InputSchema>(
@@ -70,13 +108,13 @@ export const makeSchema = <TInputSchema extends InputSchema>(
70
108
 
71
109
  const eventsDefsMap = new Map<string, EventDef.AnyWithoutFn>()
72
110
 
73
- if (isReadonlyArray(inputSchema.events)) {
111
+ if (isReadonlyArray(inputSchema.events) === true) {
74
112
  for (const eventDef of inputSchema.events) {
75
113
  eventsDefsMap.set(eventDef.name, eventDef)
76
114
  }
77
115
  } else {
78
116
  for (const eventDef of Object.values(inputSchema.events ?? {})) {
79
- if (eventsDefsMap.has(eventDef.name)) {
117
+ if (eventsDefsMap.has(eventDef.name) === true) {
80
118
  shouldNeverHappen(`Duplicate event name: ${eventDef.name}. Please use unique names for events.`)
81
119
  }
82
120
  eventsDefsMap.set(eventDef.name, eventDef)
@@ -84,17 +122,20 @@ export const makeSchema = <TInputSchema extends InputSchema>(
84
122
  }
85
123
 
86
124
  for (const tableDef of tables.values()) {
87
- if (tableIsClientDocumentTable(tableDef) && eventsDefsMap.has(tableDef.set.name) === false) {
125
+ if (tableIsClientDocumentTable(tableDef) === true && eventsDefsMap.has(tableDef.set.name) === false) {
88
126
  eventsDefsMap.set(tableDef.set.name, tableDef.set)
89
127
  }
90
128
  }
91
129
 
130
+ const unknownEventHandling = normalizeUnknownEventHandling(inputSchema.unknownEventHandling)
131
+
92
132
  return {
93
133
  LiveStoreSchemaSymbol,
94
134
  _DbSchemaType: Symbol.for('livestore.DbSchemaType') as any,
95
135
  _EventDefMapType: Symbol.for('livestore.EventDefMapType') as any,
96
136
  state,
97
137
  eventsDefsMap,
138
+ unknownEventHandling,
98
139
  devtools: {
99
140
  alias: inputSchema.devtools?.alias ?? 'default',
100
141
  },
@@ -1,9 +1,16 @@
1
- import { Schema } from '@livestore/utils/effect'
2
1
  import { describe, expect, test } from 'vitest'
3
2
 
3
+ import { Schema } from '@livestore/utils/effect'
4
+
4
5
  import { tables } from '../../../__tests__/fixture.ts'
5
- import type * as LiveStoreEvent from '../../LiveStoreEvent.ts'
6
- import { ClientDocumentTableDefSymbol, clientDocument, mergeDefaultValues } from './client-document-def.ts'
6
+ import type * as LiveStoreEvent from '../../LiveStoreEvent/mod.ts'
7
+ import {
8
+ ClientDocumentTableDefSymbol,
9
+ clientDocument,
10
+ createOptimisticEventSchema,
11
+ mergeDefaultValues,
12
+ } from './client-document-def.ts'
13
+ import { getResultSchema } from './query-builder/impl.ts'
7
14
 
8
15
  describe('client document table', () => {
9
16
  test('set event', () => {
@@ -248,14 +255,146 @@ describe('client document table', () => {
248
255
  `)
249
256
  })
250
257
  })
258
+
259
+ /** Ensures optimistic decoding stays robust when persisted JSON is incompatible. */
260
+ describe('optimistic schema', () => {
261
+ /** Models persisted JSON using epoch numbers + base64 while app code expects Date + Uint8Array. */
262
+ const valueSchema = Schema.Struct({
263
+ createdAt: Schema.DateFromNumber,
264
+ avatar: Schema.Uint8ArrayFromBase64,
265
+ })
266
+ const defaultValue = {
267
+ createdAt: new Date(0),
268
+ avatar: new Uint8Array(),
269
+ }
270
+ const invalidPayloads: Array<{ label: string; value: unknown }> = [
271
+ { label: 'decoded-shape JSON', value: { createdAt: new Date(0), avatar: new Uint8Array([1, 2]) } },
272
+ { label: 'wrong types', value: { createdAt: 'not-a-number', avatar: { nested: 'bad' } } },
273
+ { label: 'missing required fields', value: {} },
274
+ ]
275
+ const validPayload = { createdAt: 42, avatar: 'AQI=' }
276
+ const extraFieldsPayload = { createdAt: 42, avatar: 'AQI=', extra: 'ignored' }
277
+
278
+ test.each(invalidPayloads)('decodes invalid persisted JSON ($label)', ({ value }) => {
279
+ const optimisticSchema = createOptimisticEventSchema({
280
+ valueSchema,
281
+ defaultValue,
282
+ partialSet: false,
283
+ })
284
+ const rowSchema = Schema.parseJson(optimisticSchema)
285
+
286
+ expect(Schema.decodeUnknownSync(rowSchema)(JSON.stringify(value))).toEqual(defaultValue)
287
+ })
288
+
289
+ test('decodes valid persisted JSON (encoded shape)', () => {
290
+ const optimisticSchema = createOptimisticEventSchema({
291
+ valueSchema,
292
+ defaultValue,
293
+ partialSet: false,
294
+ })
295
+ const rowSchema = Schema.parseJson(optimisticSchema)
296
+
297
+ expect(Schema.decodeUnknownSync(rowSchema)(JSON.stringify(validPayload))).toEqual({
298
+ createdAt: new Date(42),
299
+ avatar: new Uint8Array([1, 2]),
300
+ })
301
+ })
302
+
303
+ test('decodes valid persisted JSON with extra fields', () => {
304
+ const optimisticSchema = createOptimisticEventSchema({
305
+ valueSchema,
306
+ defaultValue,
307
+ partialSet: false,
308
+ })
309
+ const rowSchema = Schema.parseJson(optimisticSchema)
310
+
311
+ expect(Schema.decodeUnknownSync(rowSchema)(JSON.stringify(extraFieldsPayload))).toEqual({
312
+ createdAt: new Date(42),
313
+ avatar: new Uint8Array([1, 2]),
314
+ })
315
+ })
316
+
317
+ test.each(invalidPayloads)('decodes clientDocument rowSchema with invalid JSON ($label)', ({ value }) => {
318
+ const Doc = clientDocument({
319
+ name: 'test_numbers',
320
+ schema: valueSchema,
321
+ default: { value: defaultValue },
322
+ partialSet: false,
323
+ })
324
+ const row = {
325
+ id: 'row-1',
326
+ value: JSON.stringify(value),
327
+ }
328
+
329
+ expect(Schema.decodeUnknownSync(Doc.rowSchema)(row)).toEqual({ id: 'row-1', value: defaultValue })
330
+ })
331
+
332
+ test('decodes clientDocument rowSchema with valid encoded JSON', () => {
333
+ const Doc = clientDocument({
334
+ name: 'test_numbers',
335
+ schema: valueSchema,
336
+ default: { value: defaultValue },
337
+ partialSet: false,
338
+ })
339
+ const row = {
340
+ id: 'row-1',
341
+ value: JSON.stringify(validPayload),
342
+ }
343
+
344
+ expect(Schema.decodeUnknownSync(Doc.rowSchema)(row)).toEqual({
345
+ id: 'row-1',
346
+ value: { createdAt: new Date(42), avatar: new Uint8Array([1, 2]) },
347
+ })
348
+ })
349
+
350
+ test.each(invalidPayloads)('decodes RowQuery result schema with invalid JSON ($label)', ({ value }) => {
351
+ const Doc = clientDocument({
352
+ name: 'test_numbers',
353
+ schema: valueSchema,
354
+ default: { value: defaultValue },
355
+ partialSet: false,
356
+ })
357
+ const query = Doc.get('row-1')
358
+ const resultSchema = getResultSchema(query)
359
+ const rawDbResults = [
360
+ {
361
+ id: 'row-1',
362
+ value: JSON.stringify(value),
363
+ },
364
+ ]
365
+
366
+ expect(Schema.decodeUnknownSync(resultSchema)(rawDbResults)).toEqual(defaultValue)
367
+ })
368
+
369
+ test('decodes RowQuery result schema with valid encoded JSON', () => {
370
+ const Doc = clientDocument({
371
+ name: 'test_numbers',
372
+ schema: valueSchema,
373
+ default: { value: defaultValue },
374
+ partialSet: false,
375
+ })
376
+ const query = Doc.get('row-1')
377
+ const resultSchema = getResultSchema(query)
378
+ const rawDbResults = [
379
+ {
380
+ id: 'row-1',
381
+ value: JSON.stringify(validPayload),
382
+ },
383
+ ]
384
+
385
+ expect(Schema.decodeUnknownSync(resultSchema)(rawDbResults)).toEqual({
386
+ createdAt: new Date(42),
387
+ avatar: new Uint8Array([1, 2]),
388
+ })
389
+ })
390
+ })
251
391
  })
252
392
 
253
- const patchId = (muationEvent: LiveStoreEvent.PartialAnyDecoded) => {
393
+ const patchId = (muationEvent: LiveStoreEvent.Input.Decoded) => {
254
394
  // TODO use new id paradigm
255
395
  const id = `00000000-0000-0000-0000-000000000000`
256
396
  return { ...muationEvent, id }
257
397
  }
258
-
259
398
  describe('mergeDefaultValues', () => {
260
399
  test('merges values from both objects', () => {
261
400
  const defaults = { a: 1, b: 2 }
@@ -4,8 +4,8 @@ import { Schema } from '@livestore/utils/effect'
4
4
 
5
5
  import { SessionIdSymbol } from '../../../adapter-types.ts'
6
6
  import { sql } from '../../../util.ts'
7
- import type { EventDef, Materializer } from '../../EventDef.ts'
8
- import { defineEvent, defineMaterializer } from '../../EventDef.ts'
7
+ import type { EventDef, Materializer } from '../../EventDef/mod.ts'
8
+ import { defineEvent, defineMaterializer } from '../../EventDef/mod.ts'
9
9
  import { SqliteDsl } from './db-schema/mod.ts'
10
10
  import type { QueryBuilder, QueryBuilderAst } from './query-builder/mod.ts'
11
11
  import { QueryBuilderAstSymbol, QueryBuilderTypeId } from './query-builder/mod.ts'
@@ -95,10 +95,12 @@ export const clientDocument = <
95
95
  Object.defineProperty(setEventDef, 'schema', {
96
96
  value: Schema.Struct({
97
97
  id: Schema.String,
98
- value: options.partialSet ? Schema.partial(valueSchema) : valueSchema,
98
+ value: options.partialSet === true ? Schema.partial(valueSchema) : valueSchema,
99
99
  }).annotations({ title: `${name}Set:Args` }),
100
100
  })
101
- Object.defineProperty(setEventDef, 'options', { value: { derived: true, clientOnly: true, facts: undefined } })
101
+ Object.defineProperty(setEventDef, 'options', {
102
+ value: { derived: true, clientOnly: true, facts: undefined, deprecated: undefined },
103
+ })
102
104
 
103
105
  const clientDocumentTableDefTrait: ClientDocumentTableDef.Trait<
104
106
  TName,
@@ -106,20 +108,26 @@ export const clientDocument = <
106
108
  TEncoded,
107
109
  ClientDocumentTableOptions<TType>
108
110
  > = {
111
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- dynamic table def composition; type safety ensured by ClientDocumentTableDef.Trait
109
112
  get: makeGetQueryBuilder(() => clientDocumentTableDef) as any,
113
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- dynamic table def composition; type safety ensured by SetEventDefLike signature
110
114
  set: setEventDef as any,
115
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- phantom type field for generic inference only
111
116
  Value: 'only-for-type-inference' as any,
112
117
  default: options.default,
113
118
  valueSchema,
114
119
  [ClientDocumentTableDefSymbol]: {
115
120
  derived: {
121
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- dynamic event def composition; type checked at usage sites
116
122
  setEventDef: derivedSetEventDef as any,
123
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- dynamic materializer composition; type checked at usage sites
117
124
  setMaterializer: derivedSetMaterializer as any,
118
125
  },
119
126
  options,
120
127
  },
121
128
  }
122
129
 
130
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- composing tableDef + clientDocumentTableDefTrait into final type; validated by satisfies above
123
131
  const clientDocumentTableDef = {
124
132
  ...tableDef,
125
133
  ...clientDocumentTableDefTrait,
@@ -139,11 +147,14 @@ export const mergeDefaultValues = <T>(defaultValues: T, explicitDefaultValues: T
139
147
  }
140
148
 
141
149
  // Get all unique keys from both objects
150
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- Object.keys requires indexable type; T is constrained to object by preceding typeof checks
142
151
  const allKeys = new Set([...Object.keys(defaultValues as any), ...Object.keys(explicitDefaultValues as any)])
143
152
 
144
153
  return Array.from(allKeys).reduce((acc, key) => {
154
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- dynamic key access on generic object; keys validated from Object.keys above
145
155
  acc[key] = (explicitDefaultValues as any)[key] ?? (defaultValues as any)[key]
146
156
  return acc
157
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- reduce accumulator type; result type is T
147
158
  }, {} as any)
148
159
  }
149
160
 
@@ -175,7 +186,10 @@ export const createOptimisticEventSchema = ({
175
186
  defaultValue: any
176
187
  partialSet: boolean
177
188
  }) => {
178
- const targetSchema = partialSet ? Schema.partial(valueSchema) : valueSchema
189
+ const targetSchema = partialSet === true ? Schema.partial(valueSchema) : valueSchema
190
+ // The transform decode must yield values in the target schema's ENCODED shape.
191
+ // This keeps JSON columns consistent when Encoded != Type (e.g. Option).
192
+ const encodeTarget = Schema.encodeSync(targetSchema)
179
193
 
180
194
  return Schema.transform(
181
195
  Schema.Unknown, // Accept any historical event structure
@@ -184,17 +198,21 @@ export const createOptimisticEventSchema = ({
184
198
  decode: (eventValue) => {
185
199
  // Try direct decode first (for current schema events)
186
200
  try {
187
- return Schema.decodeUnknownSync(targetSchema)(eventValue)
201
+ const decoded = Schema.decodeUnknownSync(targetSchema)(eventValue)
202
+ // Re-encode so downstream parseJson/column decoding sees encoded values.
203
+ return encodeTarget(decoded)
188
204
  } catch {
189
205
  // Optimistic decoding for historical events
190
206
 
191
207
  // Handle null/undefined/non-object cases
192
208
  if (typeof eventValue !== 'object' || eventValue === null) {
193
- console.warn(`Client document: Non-object event value, using ${partialSet ? 'empty partial' : 'defaults'}`)
194
- return partialSet ? {} : defaultValue
209
+ console.warn(
210
+ `Client document: Non-object event value, using ${partialSet === true ? 'empty partial' : 'defaults'}`,
211
+ )
212
+ return encodeTarget(partialSet === true ? {} : defaultValue)
195
213
  }
196
214
 
197
- if (partialSet) {
215
+ if (partialSet === true) {
198
216
  // For partial sets: only preserve fields that exist in new schema
199
217
  const partialResult: Record<string, unknown> = {}
200
218
  let hasValidFields = false
@@ -207,16 +225,17 @@ export const createOptimisticEventSchema = ({
207
225
  // Drop fields that don't exist in new schema
208
226
  }
209
227
 
210
- if (hasValidFields) {
228
+ if (hasValidFields === true) {
211
229
  try {
212
- return Schema.decodeUnknownSync(targetSchema)(partialResult)
230
+ const decoded = Schema.decodeUnknownSync(targetSchema)(partialResult)
231
+ return encodeTarget(decoded)
213
232
  } catch {
214
233
  // Even filtered fields don't match schema
215
234
  console.warn('Client document: Partial fields incompatible, returning empty partial')
216
- return {}
235
+ return encodeTarget({})
217
236
  }
218
237
  }
219
- return {}
238
+ return encodeTarget({})
220
239
  } else {
221
240
  // Full set: merge old data with new defaults
222
241
  const merged: Record<string, unknown> = { ...defaultValue }
@@ -231,12 +250,13 @@ export const createOptimisticEventSchema = ({
231
250
 
232
251
  // Try to decode the merged value
233
252
  try {
234
- return Schema.decodeUnknownSync(valueSchema)(merged)
253
+ const decoded = Schema.decodeUnknownSync(valueSchema)(merged)
254
+ return encodeTarget(decoded)
235
255
  } catch {
236
256
  // Merged value still doesn't match (e.g., type changes)
237
257
  // Fall back to pure defaults
238
258
  console.warn('Client document: Could not preserve event data, using defaults')
239
- return defaultValue
259
+ return encodeTarget(defaultValue)
240
260
  }
241
261
  }
242
262
  }
@@ -357,11 +377,14 @@ const makeGetQueryBuilder = <TTableDef extends ClientDocumentTableDef<any, any,
357
377
  return {
358
378
  [QueryBuilderTypeId]: QueryBuilderTypeId,
359
379
  [QueryBuilderAstSymbol]: ast,
380
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- phantom type field for generic inference only
360
381
  ResultType: 'only-for-type-inference' as any,
361
382
  asSql: () => ({ query, bindValues: [id] }),
362
383
  toString: () => query.toString(),
384
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- spreading empty object to satisfy QueryBuilder interface requirements
363
385
  ...({} as any), // Needed for type cast
364
386
  }
387
+ // oxlint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- makeGetQueryBuilder return type uses complex conditional generics
365
388
  }) as any
366
389
  }
367
390
 
@@ -513,27 +536,17 @@ export namespace ClientDocumentTableDef {
513
536
  }
514
537
  }
515
538
 
516
- export type GetOptions<TTableDef extends TraitAny> = TTableDef extends ClientDocumentTableDef.Trait<
517
- any,
518
- any,
519
- any,
520
- infer TOptions
521
- >
522
- ? TOptions
523
- : never
539
+ export type GetOptions<TTableDef extends TraitAny> =
540
+ TTableDef extends ClientDocumentTableDef.Trait<any, any, any, infer TOptions> ? TOptions : never
524
541
 
525
542
  export type TraitAny = Trait<any, any, any, any>
526
543
 
527
- export type DefaultIdType<TTableDef extends TraitAny> = TTableDef extends ClientDocumentTableDef.Trait<
528
- any,
529
- any,
530
- any,
531
- infer TOptions
532
- >
533
- ? TOptions['default']['id'] extends SessionIdSymbol | string
534
- ? TOptions['default']['id']
544
+ export type DefaultIdType<TTableDef extends TraitAny> =
545
+ TTableDef extends ClientDocumentTableDef.Trait<any, any, any, infer TOptions>
546
+ ? TOptions['default']['id'] extends SessionIdSymbol | string
547
+ ? TOptions['default']['id']
548
+ : never
535
549
  : never
536
- : never
537
550
 
538
551
  export type SetEventDefLike<
539
552
  TName extends string,
@@ -554,7 +567,7 @@ export namespace ClientDocumentTableDef {
554
567
  readonly name: `${TName}Set`
555
568
  readonly args: { id: string; value: TType }
556
569
  }
557
- readonly options: { derived: true; clientOnly: true; facts: undefined }
570
+ readonly options: { derived: true; clientOnly: true; facts: undefined; deprecated: undefined }
558
571
  }
559
572
 
560
573
  export type SetEventDef<TName extends string, TType, TOptions extends ClientDocumentTableOptions<TType>> = EventDef<
@@ -579,5 +592,5 @@ export namespace ClientDocumentTableDef {
579
592
  ) => QueryBuilder<TType, ClientDocumentTableDef.TableDefBase_<TName, TType>, QueryBuilder.ApiFeature>
580
593
  }
581
594
 
582
- export const ClientDocumentTableDefSymbol = Symbol('ClientDocumentTableDef')
595
+ export const ClientDocumentTableDefSymbol = Symbol.for('livestore.ClientDocumentTableDef')
583
596
  export type ClientDocumentTableDefSymbol = typeof ClientDocumentTableDefSymbol
@@ -1,6 +1,7 @@
1
- import { Schema, SchemaAST } from '@livestore/utils/effect'
2
1
  import { describe, expect, test } from 'vitest'
3
2
 
3
+ import { Schema, SchemaAST } from '@livestore/utils/effect'
4
+
4
5
  import { withColumnType, withPrimaryKey } from './column-annotations.ts'
5
6
 
6
7
  describe.concurrent('annotations', () => {
@@ -65,7 +66,7 @@ describe.concurrent('annotations', () => {
65
66
  })
66
67
 
67
68
  test('Union of same type with compatible column type', () => {
68
- const unionSchema = Schema.Union(Schema.Literal('a'), Schema.Literal('b'))
69
+ const unionSchema = Schema.Literal('a', 'b')
69
70
  expect(() => withColumnType(unionSchema, 'text')).not.toThrow()
70
71
  })
71
72
 
@@ -1,5 +1,6 @@
1
1
  import type { Schema } from '@livestore/utils/effect'
2
2
  import { dual, Option, SchemaAST } from '@livestore/utils/effect'
3
+
3
4
  import type { SqliteDsl } from './db-schema/mod.ts'
4
5
 
5
6
  export const PrimaryKeyId = Symbol.for('livestore/state/sqlite/annotations/primary-key')
@@ -79,7 +80,7 @@ const validateSchemaColumnTypeCompatibility = (
79
80
  const applyAnnotations = <T extends Schema.Schema.All>(schema: T, overrides: Record<PropertyKey, unknown>): T => {
80
81
  const identifier = SchemaAST.getIdentifierAnnotation(schema.ast)
81
82
  const shouldPreserveIdentifier = Option.isSome(identifier) && !(SchemaAST.IdentifierAnnotationId in overrides)
82
- const annotations: Record<PropertyKey, unknown> = shouldPreserveIdentifier
83
+ const annotations: Record<PropertyKey, unknown> = shouldPreserveIdentifier === true
83
84
  ? { ...overrides, [SchemaAST.IdentifierAnnotationId]: identifier.value }
84
85
  : overrides
85
86