@livestore/common 0.4.0 → 0.5.0-dev.1

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 (501) 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 +8 -8
  17. package/dist/__tests__/fixture.d.ts.map +1 -1
  18. package/dist/__tests__/fixture.js +4 -4
  19. package/dist/__tests__/fixture.js.map +1 -1
  20. package/dist/adapter-types.d.ts +33 -57
  21. package/dist/adapter-types.d.ts.map +1 -1
  22. package/dist/adapter-types.js +24 -41
  23. package/dist/adapter-types.js.map +1 -1
  24. package/dist/bounded-collections.d.ts.map +1 -1
  25. package/dist/bounded-collections.js.map +1 -1
  26. package/dist/debug-info.d.ts +56 -56
  27. package/dist/debug-info.d.ts.map +1 -1
  28. package/dist/debug-info.js +32 -44
  29. package/dist/debug-info.js.map +1 -1
  30. package/dist/defs.d.ts +9 -9
  31. package/dist/defs.js +2 -2
  32. package/dist/devtools/devtools-compatibility.test.js +2 -1
  33. package/dist/devtools/devtools-compatibility.test.js.map +1 -1
  34. package/dist/devtools/devtools-messages-client-session.d.ts +522 -334
  35. package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -1
  36. package/dist/devtools/devtools-messages-client-session.js +80 -78
  37. package/dist/devtools/devtools-messages-client-session.js.map +1 -1
  38. package/dist/devtools/devtools-messages-common.d.ts +27 -27
  39. package/dist/devtools/devtools-messages-common.d.ts.map +1 -1
  40. package/dist/devtools/devtools-messages-common.js +6 -6
  41. package/dist/devtools/devtools-messages-common.js.map +1 -1
  42. package/dist/devtools/devtools-messages-leader.d.ts +410 -348
  43. package/dist/devtools/devtools-messages-leader.d.ts.map +1 -1
  44. package/dist/devtools/devtools-messages-leader.js +105 -93
  45. package/dist/devtools/devtools-messages-leader.js.map +1 -1
  46. package/dist/devtools/devtools-messages.js +3 -3
  47. package/dist/devtools/devtools-sessioninfo.d.ts +18 -19
  48. package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -1
  49. package/dist/devtools/devtools-sessioninfo.js +8 -5
  50. package/dist/devtools/devtools-sessioninfo.js.map +1 -1
  51. package/dist/devtools/mod.d.ts +4 -5
  52. package/dist/devtools/mod.d.ts.map +1 -1
  53. package/dist/devtools/mod.js +12 -8
  54. package/dist/devtools/mod.js.map +1 -1
  55. package/dist/errors.d.ts +45 -69
  56. package/dist/errors.d.ts.map +1 -1
  57. package/dist/errors.js +19 -17
  58. package/dist/errors.js.map +1 -1
  59. package/dist/index.d.ts +4 -1
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +22 -19
  62. package/dist/index.js.map +1 -1
  63. package/dist/leader-thread/LeaderSyncProcessor.d.ts +87 -18
  64. package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
  65. package/dist/leader-thread/LeaderSyncProcessor.js +548 -480
  66. package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
  67. package/dist/leader-thread/RejectedPushError.d.ts +72 -41
  68. package/dist/leader-thread/RejectedPushError.d.ts.map +1 -1
  69. package/dist/leader-thread/RejectedPushError.js +25 -6
  70. package/dist/leader-thread/RejectedPushError.js.map +1 -1
  71. package/dist/leader-thread/connection.d.ts +1 -0
  72. package/dist/leader-thread/connection.d.ts.map +1 -1
  73. package/dist/leader-thread/connection.js +11 -10
  74. package/dist/leader-thread/connection.js.map +1 -1
  75. package/dist/leader-thread/eventlog.d.ts +15 -5
  76. package/dist/leader-thread/eventlog.d.ts.map +1 -1
  77. package/dist/leader-thread/eventlog.js +19 -19
  78. package/dist/leader-thread/eventlog.js.map +1 -1
  79. package/dist/leader-thread/leader-worker-devtools.d.ts +1 -1
  80. package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
  81. package/dist/leader-thread/leader-worker-devtools.js +36 -20
  82. package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
  83. package/dist/leader-thread/make-leader-thread-layer.d.ts +15 -5
  84. package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
  85. package/dist/leader-thread/make-leader-thread-layer.js +62 -58
  86. package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
  87. package/dist/leader-thread/make-leader-thread-layer.test.js +9 -9
  88. package/dist/leader-thread/make-leader-thread-layer.test.js.map +1 -1
  89. package/dist/leader-thread/materialize-event.d.ts +2 -1
  90. package/dist/leader-thread/materialize-event.d.ts.map +1 -1
  91. package/dist/leader-thread/materialize-event.js +12 -8
  92. package/dist/leader-thread/materialize-event.js.map +1 -1
  93. package/dist/leader-thread/mod.js +9 -9
  94. package/dist/leader-thread/recreate-db.d.ts +5 -1
  95. package/dist/leader-thread/recreate-db.d.ts.map +1 -1
  96. package/dist/leader-thread/recreate-db.js +34 -59
  97. package/dist/leader-thread/recreate-db.js.map +1 -1
  98. package/dist/leader-thread/shutdown-channel.d.ts +2 -6
  99. package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
  100. package/dist/leader-thread/shutdown-channel.js +2 -3
  101. package/dist/leader-thread/shutdown-channel.js.map +1 -1
  102. package/dist/leader-thread/stream-events.d.ts +4 -7
  103. package/dist/leader-thread/stream-events.d.ts.map +1 -1
  104. package/dist/leader-thread/stream-events.js +16 -21
  105. package/dist/leader-thread/stream-events.js.map +1 -1
  106. package/dist/leader-thread/types.d.ts +38 -73
  107. package/dist/leader-thread/types.d.ts.map +1 -1
  108. package/dist/leader-thread/types.js +10 -6
  109. package/dist/leader-thread/types.js.map +1 -1
  110. package/dist/logging.d.ts +5 -30
  111. package/dist/logging.d.ts.map +1 -1
  112. package/dist/logging.js +1 -32
  113. package/dist/logging.js.map +1 -1
  114. package/dist/make-client-session.d.ts +2 -3
  115. package/dist/make-client-session.d.ts.map +1 -1
  116. package/dist/make-client-session.js +5 -5
  117. package/dist/make-client-session.js.map +1 -1
  118. package/dist/materializer-helper.d.ts +0 -1
  119. package/dist/materializer-helper.d.ts.map +1 -1
  120. package/dist/materializer-helper.js +9 -37
  121. package/dist/materializer-helper.js.map +1 -1
  122. package/dist/otel.d.ts +2 -3
  123. package/dist/otel.d.ts.map +1 -1
  124. package/dist/otel.js +2 -7
  125. package/dist/otel.js.map +1 -1
  126. package/dist/rematerialize-from-eventlog.d.ts +3 -1
  127. package/dist/rematerialize-from-eventlog.d.ts.map +1 -1
  128. package/dist/rematerialize-from-eventlog.js +42 -33
  129. package/dist/rematerialize-from-eventlog.js.map +1 -1
  130. package/dist/schema/EventDef/define.d.ts +6 -6
  131. package/dist/schema/EventDef/define.d.ts.map +1 -1
  132. package/dist/schema/EventDef/define.js +5 -5
  133. package/dist/schema/EventDef/define.js.map +1 -1
  134. package/dist/schema/EventDef/define.test.d.ts +2 -0
  135. package/dist/schema/EventDef/define.test.d.ts.map +1 -0
  136. package/dist/schema/EventDef/define.test.js +23 -0
  137. package/dist/schema/EventDef/define.test.js.map +1 -0
  138. package/dist/schema/EventDef/deprecated.d.ts +8 -13
  139. package/dist/schema/EventDef/deprecated.d.ts.map +1 -1
  140. package/dist/schema/EventDef/deprecated.js +12 -13
  141. package/dist/schema/EventDef/deprecated.js.map +1 -1
  142. package/dist/schema/EventDef/deprecated.test.js +3 -3
  143. package/dist/schema/EventDef/deprecated.test.js.map +1 -1
  144. package/dist/schema/EventDef/event-def.d.ts +1 -1
  145. package/dist/schema/EventDef/event-def.d.ts.map +1 -1
  146. package/dist/schema/EventDef/facts.d.ts.map +1 -1
  147. package/dist/schema/EventDef/materializer.d.ts +2 -2
  148. package/dist/schema/EventDef/materializer.d.ts.map +1 -1
  149. package/dist/schema/EventDef/mod.js +5 -5
  150. package/dist/schema/EventSequenceNumber/client.d.ts +12 -17
  151. package/dist/schema/EventSequenceNumber/client.d.ts.map +1 -1
  152. package/dist/schema/EventSequenceNumber/client.js +20 -24
  153. package/dist/schema/EventSequenceNumber/client.js.map +1 -1
  154. package/dist/schema/EventSequenceNumber/global.d.ts +2 -2
  155. package/dist/schema/EventSequenceNumber/global.d.ts.map +1 -1
  156. package/dist/schema/EventSequenceNumber/global.js +1 -1
  157. package/dist/schema/EventSequenceNumber/global.js.map +1 -1
  158. package/dist/schema/EventSequenceNumber/mod.js +2 -2
  159. package/dist/schema/EventSequenceNumber.test.js +6 -6
  160. package/dist/schema/EventSequenceNumber.test.js.map +1 -1
  161. package/dist/schema/LiveStoreEvent/client.d.ts +58 -187
  162. package/dist/schema/LiveStoreEvent/client.d.ts.map +1 -1
  163. package/dist/schema/LiveStoreEvent/client.js +33 -30
  164. package/dist/schema/LiveStoreEvent/client.js.map +1 -1
  165. package/dist/schema/LiveStoreEvent/client.test.js +13 -4
  166. package/dist/schema/LiveStoreEvent/client.test.js.map +1 -1
  167. package/dist/schema/LiveStoreEvent/for-event-def.d.ts +7 -7
  168. package/dist/schema/LiveStoreEvent/for-event-def.d.ts.map +1 -1
  169. package/dist/schema/LiveStoreEvent/global.d.ts +6 -6
  170. package/dist/schema/LiveStoreEvent/global.d.ts.map +1 -1
  171. package/dist/schema/LiveStoreEvent/global.js +2 -2
  172. package/dist/schema/LiveStoreEvent/global.js.map +1 -1
  173. package/dist/schema/LiveStoreEvent/input.d.ts +6 -6
  174. package/dist/schema/LiveStoreEvent/input.d.ts.map +1 -1
  175. package/dist/schema/LiveStoreEvent/input.js +3 -3
  176. package/dist/schema/LiveStoreEvent/input.js.map +1 -1
  177. package/dist/schema/LiveStoreEvent/mod.js +4 -4
  178. package/dist/schema/events.js +1 -1
  179. package/dist/schema/mod.d.ts +1 -0
  180. package/dist/schema/mod.d.ts.map +1 -1
  181. package/dist/schema/mod.js +11 -10
  182. package/dist/schema/mod.js.map +1 -1
  183. package/dist/schema/schema.d.ts +1 -1
  184. package/dist/schema/schema.d.ts.map +1 -1
  185. package/dist/schema/schema.js +6 -5
  186. package/dist/schema/schema.js.map +1 -1
  187. package/dist/schema/state/mod.js +2 -2
  188. package/dist/schema/state/sqlite/client-document-def.d.ts +13 -18
  189. package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -1
  190. package/dist/schema/state/sqlite/client-document-def.js +30 -27
  191. package/dist/schema/state/sqlite/client-document-def.js.map +1 -1
  192. package/dist/schema/state/sqlite/client-document-def.test.js +53 -18
  193. package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -1
  194. package/dist/schema/state/sqlite/column-annotations.d.ts +13 -13
  195. package/dist/schema/state/sqlite/column-annotations.d.ts.map +1 -1
  196. package/dist/schema/state/sqlite/column-annotations.js +13 -15
  197. package/dist/schema/state/sqlite/column-annotations.js.map +1 -1
  198. package/dist/schema/state/sqlite/column-annotations.test.js +19 -43
  199. package/dist/schema/state/sqlite/column-annotations.test.js.map +1 -1
  200. package/dist/schema/state/sqlite/column-def.d.ts +1 -1
  201. package/dist/schema/state/sqlite/column-def.d.ts.map +1 -1
  202. package/dist/schema/state/sqlite/column-def.js +73 -33
  203. package/dist/schema/state/sqlite/column-def.js.map +1 -1
  204. package/dist/schema/state/sqlite/column-def.test.js +176 -75
  205. package/dist/schema/state/sqlite/column-def.test.js.map +1 -1
  206. package/dist/schema/state/sqlite/column-spec.d.ts.map +1 -1
  207. package/dist/schema/state/sqlite/column-spec.js +1 -1
  208. package/dist/schema/state/sqlite/column-spec.js.map +1 -1
  209. package/dist/schema/state/sqlite/column-spec.test.js +4 -4
  210. package/dist/schema/state/sqlite/column-spec.test.js.map +1 -1
  211. package/dist/schema/state/sqlite/db-schema/ast/fingerprint-digest.d.ts +3 -0
  212. package/dist/schema/state/sqlite/db-schema/ast/fingerprint-digest.d.ts.map +1 -0
  213. package/dist/schema/state/sqlite/db-schema/ast/fingerprint-digest.js +5 -0
  214. package/dist/schema/state/sqlite/db-schema/ast/fingerprint-digest.js.map +1 -0
  215. package/dist/schema/state/sqlite/db-schema/ast/fingerprint.d.ts +5 -0
  216. package/dist/schema/state/sqlite/db-schema/ast/fingerprint.d.ts.map +1 -0
  217. package/dist/schema/state/sqlite/db-schema/ast/fingerprint.js +183 -0
  218. package/dist/schema/state/sqlite/db-schema/ast/fingerprint.js.map +1 -0
  219. package/dist/schema/state/sqlite/db-schema/ast/fingerprint.test.d.ts +2 -0
  220. package/dist/schema/state/sqlite/db-schema/ast/fingerprint.test.d.ts.map +1 -0
  221. package/dist/schema/state/sqlite/db-schema/ast/fingerprint.test.js +142 -0
  222. package/dist/schema/state/sqlite/db-schema/ast/fingerprint.test.js.map +1 -0
  223. package/dist/schema/state/sqlite/db-schema/ast/sqlite.d.ts +3 -8
  224. package/dist/schema/state/sqlite/db-schema/ast/sqlite.d.ts.map +1 -1
  225. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js +1 -73
  226. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js.map +1 -1
  227. package/dist/schema/state/sqlite/db-schema/ast/validate.d.ts.map +1 -1
  228. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts +9 -9
  229. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts.map +1 -1
  230. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js +9 -13
  231. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js.map +1 -1
  232. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js +28 -17
  233. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js.map +1 -1
  234. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts +13 -11
  235. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts.map +1 -1
  236. package/dist/schema/state/sqlite/db-schema/dsl/mod.js +6 -4
  237. package/dist/schema/state/sqlite/db-schema/dsl/mod.js.map +1 -1
  238. package/dist/schema/state/sqlite/db-schema/has-json-string-encoding.d.ts +3 -0
  239. package/dist/schema/state/sqlite/db-schema/has-json-string-encoding.d.ts.map +1 -0
  240. package/dist/schema/state/sqlite/db-schema/has-json-string-encoding.js +6 -0
  241. package/dist/schema/state/sqlite/db-schema/has-json-string-encoding.js.map +1 -0
  242. package/dist/schema/state/sqlite/db-schema/mod.js +2 -2
  243. package/dist/schema/state/sqlite/mod.d.ts +1 -3
  244. package/dist/schema/state/sqlite/mod.d.ts.map +1 -1
  245. package/dist/schema/state/sqlite/mod.js +11 -10
  246. package/dist/schema/state/sqlite/mod.js.map +1 -1
  247. package/dist/schema/state/sqlite/persistence.d.ts +11 -0
  248. package/dist/schema/state/sqlite/persistence.d.ts.map +1 -0
  249. package/dist/schema/state/sqlite/persistence.js +10 -0
  250. package/dist/schema/state/sqlite/persistence.js.map +1 -0
  251. package/dist/schema/state/sqlite/query-builder/api.d.ts +7 -7
  252. package/dist/schema/state/sqlite/query-builder/api.d.ts.map +1 -1
  253. package/dist/schema/state/sqlite/query-builder/astToSql.d.ts.map +1 -1
  254. package/dist/schema/state/sqlite/query-builder/astToSql.js +22 -23
  255. package/dist/schema/state/sqlite/query-builder/astToSql.js.map +1 -1
  256. package/dist/schema/state/sqlite/query-builder/impl.d.ts +1 -1
  257. package/dist/schema/state/sqlite/query-builder/impl.d.ts.map +1 -1
  258. package/dist/schema/state/sqlite/query-builder/impl.js +18 -16
  259. package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -1
  260. package/dist/schema/state/sqlite/query-builder/impl.test.js +364 -598
  261. package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -1
  262. package/dist/schema/state/sqlite/query-builder/mod.js +2 -2
  263. package/dist/schema/state/sqlite/schema-helpers.d.ts.map +1 -1
  264. package/dist/schema/state/sqlite/schema-helpers.js +2 -2
  265. package/dist/schema/state/sqlite/schema-helpers.js.map +1 -1
  266. package/dist/schema/state/sqlite/schema-helpers.test.js +2 -2
  267. package/dist/schema/state/sqlite/system-tables/eventlog-tables.d.ts +102 -134
  268. package/dist/schema/state/sqlite/system-tables/eventlog-tables.d.ts.map +1 -1
  269. package/dist/schema/state/sqlite/system-tables/eventlog-tables.js +5 -5
  270. package/dist/schema/state/sqlite/system-tables/eventlog-tables.js.map +1 -1
  271. package/dist/schema/state/sqlite/system-tables/mod.js +2 -2
  272. package/dist/schema/state/sqlite/system-tables/state-tables.d.ts +380 -115
  273. package/dist/schema/state/sqlite/system-tables/state-tables.d.ts.map +1 -1
  274. package/dist/schema/state/sqlite/system-tables/state-tables.js +47 -6
  275. package/dist/schema/state/sqlite/system-tables/state-tables.js.map +1 -1
  276. package/dist/schema/state/sqlite/table-def.d.ts +17 -20
  277. package/dist/schema/state/sqlite/table-def.d.ts.map +1 -1
  278. package/dist/schema/state/sqlite/table-def.js +72 -6
  279. package/dist/schema/state/sqlite/table-def.js.map +1 -1
  280. package/dist/schema/state/sqlite/table-def.test.js +207 -37
  281. package/dist/schema/state/sqlite/table-def.test.js.map +1 -1
  282. package/dist/schema/unknown-events.d.ts.map +1 -1
  283. package/dist/schema/unknown-events.js +3 -2
  284. package/dist/schema/unknown-events.js.map +1 -1
  285. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js +28 -6
  286. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js.map +1 -1
  287. package/dist/schema-management/common.d.ts.map +1 -1
  288. package/dist/schema-management/common.js +2 -2
  289. package/dist/schema-management/migrations.d.ts +4 -4
  290. package/dist/schema-management/migrations.d.ts.map +1 -1
  291. package/dist/schema-management/migrations.js +9 -9
  292. package/dist/schema-management/migrations.js.map +1 -1
  293. package/dist/schema-management/validate-schema.d.ts.map +1 -1
  294. package/dist/schema-management/validate-schema.js +1 -1
  295. package/dist/session-id-symbol.d.ts +29 -0
  296. package/dist/session-id-symbol.d.ts.map +1 -0
  297. package/dist/session-id-symbol.js +44 -0
  298. package/dist/session-id-symbol.js.map +1 -0
  299. package/dist/sql-queries/index.js +3 -3
  300. package/dist/sql-queries/sql-queries.d.ts.map +1 -1
  301. package/dist/sql-queries/sql-queries.js +11 -13
  302. package/dist/sql-queries/sql-queries.js.map +1 -1
  303. package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
  304. package/dist/sql-queries/sql-query-builder.js +1 -1
  305. package/dist/sql-queries/types.d.ts +6 -7
  306. package/dist/sql-queries/types.d.ts.map +1 -1
  307. package/dist/sql-queries/types.js.map +1 -1
  308. package/dist/sqlite-db-helper.d.ts +23 -3
  309. package/dist/sqlite-db-helper.d.ts.map +1 -1
  310. package/dist/sqlite-db-helper.js +39 -4
  311. package/dist/sqlite-db-helper.js.map +1 -1
  312. package/dist/sqlite-types.d.ts +3 -6
  313. package/dist/sqlite-types.d.ts.map +1 -1
  314. package/dist/sqlite-types.js +3 -3
  315. package/dist/sqlite-types.js.map +1 -1
  316. package/dist/sync/ClientSessionSyncProcessor.d.ts +41 -19
  317. package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
  318. package/dist/sync/ClientSessionSyncProcessor.js +200 -70
  319. package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
  320. package/dist/sync/errors.d.ts +12 -18
  321. package/dist/sync/errors.d.ts.map +1 -1
  322. package/dist/sync/errors.js +3 -3
  323. package/dist/sync/errors.js.map +1 -1
  324. package/dist/sync/index.js +6 -6
  325. package/dist/sync/mock-sync-backend.d.ts +2 -3
  326. package/dist/sync/mock-sync-backend.d.ts.map +1 -1
  327. package/dist/sync/mock-sync-backend.js +58 -37
  328. package/dist/sync/mock-sync-backend.js.map +1 -1
  329. package/dist/sync/mock-sync-backend.test.d.ts +2 -0
  330. package/dist/sync/mock-sync-backend.test.d.ts.map +1 -0
  331. package/dist/sync/mock-sync-backend.test.js +49 -0
  332. package/dist/sync/mock-sync-backend.test.js.map +1 -0
  333. package/dist/sync/next/compact-events.d.ts.map +1 -1
  334. package/dist/sync/next/compact-events.js +3 -3
  335. package/dist/sync/next/facts.d.ts.map +1 -1
  336. package/dist/sync/next/facts.js +1 -1
  337. package/dist/sync/next/history-dag-common.d.ts +5 -1
  338. package/dist/sync/next/history-dag-common.d.ts.map +1 -1
  339. package/dist/sync/next/history-dag-common.js +53 -32
  340. package/dist/sync/next/history-dag-common.js.map +1 -1
  341. package/dist/sync/next/history-dag.d.ts.map +1 -1
  342. package/dist/sync/next/history-dag.js +5 -4
  343. package/dist/sync/next/history-dag.js.map +1 -1
  344. package/dist/sync/next/mod.js +5 -5
  345. package/dist/sync/next/rebase-events.d.ts.map +1 -1
  346. package/dist/sync/next/rebase-events.js +2 -2
  347. package/dist/sync/next/test/compact-events.calculator.test.js +6 -6
  348. package/dist/sync/next/test/compact-events.test.js +4 -4
  349. package/dist/sync/next/test/event-fixtures.d.ts +8 -8
  350. package/dist/sync/next/test/event-fixtures.d.ts.map +1 -1
  351. package/dist/sync/next/test/event-fixtures.js +6 -6
  352. package/dist/sync/next/test/event-fixtures.js.map +1 -1
  353. package/dist/sync/next/test/history-dag-common.test.d.ts +2 -0
  354. package/dist/sync/next/test/history-dag-common.test.d.ts.map +1 -0
  355. package/dist/sync/next/test/history-dag-common.test.js +73 -0
  356. package/dist/sync/next/test/history-dag-common.test.js.map +1 -0
  357. package/dist/sync/next/test/mod.js +1 -1
  358. package/dist/sync/sync-backend-kv.d.ts.map +1 -1
  359. package/dist/sync/sync-backend-kv.js +5 -3
  360. package/dist/sync/sync-backend-kv.js.map +1 -1
  361. package/dist/sync/sync-backend.d.ts +15 -15
  362. package/dist/sync/sync-backend.d.ts.map +1 -1
  363. package/dist/sync/sync-backend.js +10 -6
  364. package/dist/sync/sync-backend.js.map +1 -1
  365. package/dist/sync/sync.d.ts +1 -1
  366. package/dist/sync/sync.d.ts.map +1 -1
  367. package/dist/sync/sync.js +2 -2
  368. package/dist/sync/syncstate.d.ts +100 -176
  369. package/dist/sync/syncstate.d.ts.map +1 -1
  370. package/dist/sync/syncstate.js +36 -39
  371. package/dist/sync/syncstate.js.map +1 -1
  372. package/dist/sync/syncstate.test.js +103 -64
  373. package/dist/sync/syncstate.test.js.map +1 -1
  374. package/dist/sync/transport-chunking.d.ts +15 -16
  375. package/dist/sync/transport-chunking.d.ts.map +1 -1
  376. package/dist/sync/transport-chunking.js +23 -32
  377. package/dist/sync/transport-chunking.js.map +1 -1
  378. package/dist/sync/validate-push-payload.d.ts.map +1 -1
  379. package/dist/sync/validate-push-payload.js +2 -2
  380. package/dist/testing/event-factory.d.ts.map +1 -1
  381. package/dist/testing/event-factory.js +2 -2
  382. package/dist/testing/event-factory.js.map +1 -1
  383. package/dist/testing/mod.js +1 -1
  384. package/dist/util.d.ts +11 -4
  385. package/dist/util.d.ts.map +1 -1
  386. package/dist/util.js +20 -2
  387. package/dist/util.js.map +1 -1
  388. package/dist/version.d.ts.map +1 -1
  389. package/dist/version.js.map +1 -1
  390. package/package.json +40 -57
  391. package/src/ClientSessionLeaderThreadProxy.ts +1 -1
  392. package/src/MaterializationJournal.ts +184 -0
  393. package/src/StateHead.ts +80 -0
  394. package/src/WorkerTransportError.ts +4 -4
  395. package/src/__tests__/fixture.ts +3 -3
  396. package/src/adapter-types.ts +28 -61
  397. package/src/debug-info.ts +53 -70
  398. package/src/defs.ts +2 -2
  399. package/src/devtools/devtools-compatibility.test.ts +1 -0
  400. package/src/devtools/devtools-messages-client-session.ts +56 -65
  401. package/src/devtools/devtools-messages-common.ts +12 -11
  402. package/src/devtools/devtools-messages-leader.ts +71 -69
  403. package/src/devtools/devtools-sessioninfo.ts +13 -11
  404. package/src/devtools/mod.ts +4 -5
  405. package/src/errors.ts +46 -34
  406. package/src/index.ts +8 -1
  407. package/src/leader-thread/LeaderSyncProcessor.ts +777 -650
  408. package/src/leader-thread/RejectedPushError.ts +40 -27
  409. package/src/leader-thread/connection.ts +12 -8
  410. package/src/leader-thread/eventlog.ts +20 -12
  411. package/src/leader-thread/leader-worker-devtools.ts +38 -20
  412. package/src/leader-thread/make-leader-thread-layer.test.ts +7 -7
  413. package/src/leader-thread/make-leader-thread-layer.ts +100 -71
  414. package/src/leader-thread/materialize-event.ts +13 -8
  415. package/src/leader-thread/recreate-db.ts +41 -75
  416. package/src/leader-thread/shutdown-channel.ts +3 -14
  417. package/src/leader-thread/stream-events.ts +102 -101
  418. package/src/leader-thread/types.ts +29 -62
  419. package/src/logging.ts +5 -52
  420. package/src/make-client-session.ts +6 -6
  421. package/src/materializer-helper.ts +7 -36
  422. package/src/otel.ts +5 -14
  423. package/src/rematerialize-from-eventlog.ts +116 -98
  424. package/src/schema/EventDef/define.test.ts +28 -0
  425. package/src/schema/EventDef/define.ts +20 -19
  426. package/src/schema/EventDef/deprecated.test.ts +1 -8
  427. package/src/schema/EventDef/deprecated.ts +17 -20
  428. package/src/schema/EventDef/event-def.ts +2 -4
  429. package/src/schema/EventSequenceNumber/client.ts +20 -24
  430. package/src/schema/EventSequenceNumber/global.ts +1 -1
  431. package/src/schema/EventSequenceNumber.test.ts +5 -5
  432. package/src/schema/LiveStoreEvent/client.test.ts +17 -4
  433. package/src/schema/LiveStoreEvent/client.ts +36 -35
  434. package/src/schema/LiveStoreEvent/for-event-def.ts +7 -7
  435. package/src/schema/LiveStoreEvent/global.ts +1 -1
  436. package/src/schema/LiveStoreEvent/input.ts +6 -6
  437. package/src/schema/mod.ts +1 -0
  438. package/src/schema/schema.ts +4 -3
  439. package/src/schema/state/sqlite/client-document-def.test.ts +55 -20
  440. package/src/schema/state/sqlite/client-document-def.ts +95 -80
  441. package/src/schema/state/sqlite/column-annotations.test.ts +26 -45
  442. package/src/schema/state/sqlite/column-annotations.ts +26 -30
  443. package/src/schema/state/sqlite/column-def.test.ts +213 -77
  444. package/src/schema/state/sqlite/column-def.ts +87 -37
  445. package/src/schema/state/sqlite/column-spec.test.ts +2 -2
  446. package/src/schema/state/sqlite/column-spec.ts +3 -2
  447. package/src/schema/state/sqlite/db-schema/ast/fingerprint-digest.ts +6 -0
  448. package/src/schema/state/sqlite/db-schema/ast/fingerprint.test.ts +209 -0
  449. package/src/schema/state/sqlite/db-schema/ast/fingerprint.ts +225 -0
  450. package/src/schema/state/sqlite/db-schema/ast/sqlite.ts +2 -81
  451. package/src/schema/state/sqlite/db-schema/dsl/__snapshots__/field-defs.test.ts.snap +123 -63
  452. package/src/schema/state/sqlite/db-schema/dsl/field-defs.test.ts +35 -16
  453. package/src/schema/state/sqlite/db-schema/dsl/field-defs.ts +26 -31
  454. package/src/schema/state/sqlite/db-schema/dsl/mod.ts +35 -21
  455. package/src/schema/state/sqlite/db-schema/has-json-string-encoding.ts +9 -0
  456. package/src/schema/state/sqlite/mod.ts +4 -5
  457. package/src/schema/state/sqlite/persistence.ts +11 -0
  458. package/src/schema/state/sqlite/query-builder/api.ts +9 -9
  459. package/src/schema/state/sqlite/query-builder/astToSql.ts +24 -26
  460. package/src/schema/state/sqlite/query-builder/impl.test.ts +433 -669
  461. package/src/schema/state/sqlite/query-builder/impl.ts +19 -15
  462. package/src/schema/state/sqlite/schema-helpers.ts +1 -1
  463. package/src/schema/state/sqlite/system-tables/eventlog-tables.ts +2 -2
  464. package/src/schema/state/sqlite/system-tables/state-tables.ts +54 -3
  465. package/src/schema/state/sqlite/table-def.test.ts +270 -66
  466. package/src/schema/state/sqlite/table-def.ts +112 -45
  467. package/src/schema/unknown-events.ts +3 -2
  468. package/src/schema-management/__tests__/migrations-autoincrement-quoting.test.ts +35 -4
  469. package/src/schema-management/migrations.ts +7 -6
  470. package/src/session-id-symbol.ts +59 -0
  471. package/src/sql-queries/sql-queries.ts +9 -13
  472. package/src/sql-queries/types.ts +6 -7
  473. package/src/sqlite-db-helper.ts +64 -2
  474. package/src/sqlite-types.ts +5 -8
  475. package/src/sync/ClientSessionSyncProcessor.ts +303 -119
  476. package/src/sync/errors.ts +14 -12
  477. package/src/sync/mock-sync-backend.test.ts +78 -0
  478. package/src/sync/mock-sync-backend.ts +93 -47
  479. package/src/sync/next/history-dag-common.ts +60 -34
  480. package/src/sync/next/history-dag.ts +4 -1
  481. package/src/sync/next/test/compact-events.calculator.test.ts +2 -2
  482. package/src/sync/next/test/event-fixtures.ts +1 -1
  483. package/src/sync/next/test/history-dag-common.test.ts +87 -0
  484. package/src/sync/sync-backend-kv.ts +4 -2
  485. package/src/sync/sync-backend.ts +15 -15
  486. package/src/sync/sync.ts +1 -1
  487. package/src/sync/syncstate.test.ts +191 -140
  488. package/src/sync/syncstate.ts +63 -53
  489. package/src/sync/transport-chunking.ts +34 -39
  490. package/src/util.ts +19 -9
  491. package/src/version.ts +1 -2
  492. package/dist/schema/state/sqlite/db-schema/hash.d.ts +0 -2
  493. package/dist/schema/state/sqlite/db-schema/hash.d.ts.map +0 -1
  494. package/dist/schema/state/sqlite/db-schema/hash.js +0 -15
  495. package/dist/schema/state/sqlite/db-schema/hash.js.map +0 -1
  496. package/dist/sql-queries/misc.d.ts +0 -2
  497. package/dist/sql-queries/misc.d.ts.map +0 -1
  498. package/dist/sql-queries/misc.js +0 -2
  499. package/dist/sql-queries/misc.js.map +0 -1
  500. package/src/schema/state/sqlite/db-schema/hash.ts +0 -13
  501. package/src/sql-queries/misc.ts +0 -2
@@ -12,19 +12,19 @@ import { SqliteDsl } from './db-schema/mod.ts'
12
12
  * Fields with both null and undefined will emit a warning as this is a lossy conversion.
13
13
  */
14
14
  export const getColumnDefForSchema = (
15
- schema: Schema.Schema.AnyNoContext,
15
+ schema: Schema.Top,
16
16
  propertySignature?: SchemaAST.PropertySignature,
17
17
  forceNullable = false,
18
18
  ): SqliteDsl.ColumnDefinition.Any => {
19
19
  const ast = schema.ast
20
20
 
21
21
  // Extract annotations
22
- const getAnnotation = <T>(annotationId: symbol): Option.Option<T> =>
22
+ const getAnnotation = <T>(annotationId: string): Option.Option<T> =>
23
23
  propertySignature !== undefined
24
24
  ? hasPropertyAnnotation<T>(propertySignature, annotationId)
25
- : SchemaAST.getAnnotation<T>(annotationId)(ast)
25
+ : Option.fromUndefinedOr(SchemaAST.resolveAt<T>(annotationId)(ast))
26
26
 
27
- const columnType = SchemaAST.getAnnotation<SqliteDsl.FieldColumnType>(ColumnType)(ast)
27
+ const columnType = Option.fromUndefinedOr(SchemaAST.resolveAt<SqliteDsl.FieldColumnType>(ColumnType)(ast))
28
28
 
29
29
  // Check if schema has null (e.g., Schema.NullOr) or undefined or if it's forced nullable (optional field)
30
30
  const isNullable = forceNullable === true || hasNull(ast) === true || hasUndefined(ast) === true
@@ -50,13 +50,13 @@ export const getColumnDefForSchema = (
50
50
 
51
51
  const hasPropertyAnnotation = <T>(
52
52
  propertySignature: SchemaAST.PropertySignature,
53
- annotationId: symbol,
53
+ annotationId: string,
54
54
  ): Option.Option<T> => {
55
- if ('annotations' in propertySignature && propertySignature.annotations !== undefined) {
56
- const annotation = SchemaAST.getAnnotation<T>(annotationId)(propertySignature as any)
57
- if (Option.isSome(annotation) === true) return annotation
55
+ const keyAnnotation = propertySignature.type.context?.annotations?.[annotationId] as T | undefined
56
+ if (keyAnnotation !== undefined) {
57
+ return Option.some(keyAnnotation)
58
58
  }
59
- return SchemaAST.getAnnotation<T>(annotationId)(propertySignature.type)
59
+ return Option.fromUndefinedOr(SchemaAST.resolveAt<T>(annotationId)(propertySignature.type))
60
60
  }
61
61
 
62
62
  /**
@@ -72,10 +72,11 @@ export const schemaFieldsToColumns = (
72
72
  for (const prop of propertySignatures) {
73
73
  if (typeof prop.name !== 'string') continue
74
74
 
75
- const fieldSchema = Schema.make(prop.type)
75
+ const isOptional = SchemaAST.isOptional(prop.type)
76
+ const fieldSchema = Schema.make<Schema.Top>(prop.type)
76
77
 
77
78
  // Warn about lossy conversion for fields with both null and undefined
78
- if (prop.isOptional === true) {
79
+ if (isOptional === true) {
79
80
  const { hasNull, hasUndefined } = checkNullUndefined(fieldSchema.ast)
80
81
  if (hasNull === true && hasUndefined === true) {
81
82
  console.warn(`Field '${prop.name}' has both null and undefined - treating | undefined as | null`)
@@ -83,7 +84,7 @@ export const schemaFieldsToColumns = (
83
84
  }
84
85
 
85
86
  // Get column definition - pass nullable flag for optional fields
86
- const columnDef = getColumnDefForSchema(fieldSchema, prop, prop.isOptional === true)
87
+ const columnDef = getColumnDefForSchema(fieldSchema, prop, isOptional === true)
87
88
 
88
89
  // Check for primary key and unique annotations
89
90
  const hasPrimaryKey = hasPropertyAnnotation<boolean>(prop, PrimaryKeyId).pipe(Option.getOrElse(() => false))
@@ -112,8 +113,8 @@ const checkNullUndefined = (ast: SchemaAST.AST): { hasNull: boolean; hasUndefine
112
113
  let hasUndefined = false
113
114
 
114
115
  const visit = (type: SchemaAST.AST): void => {
115
- if (SchemaAST.isUndefinedKeyword(type) === true) hasUndefined = true
116
- else if (SchemaAST.isLiteral(type) === true && type.literal === null) hasNull = true
116
+ if (SchemaAST.isUndefined(type) === true) hasUndefined = true
117
+ else if (SchemaAST.isNull(type) === true) hasNull = true
117
118
  else if (SchemaAST.isUnion(type) === true) type.types.forEach(visit)
118
119
  }
119
120
 
@@ -122,7 +123,7 @@ const checkNullUndefined = (ast: SchemaAST.AST): { hasNull: boolean; hasUndefine
122
123
  }
123
124
 
124
125
  const hasNull = (ast: SchemaAST.AST): boolean => {
125
- if (SchemaAST.isLiteral(ast) === true && ast.literal === null) return true
126
+ if (SchemaAST.isNull(ast) === true) return true
126
127
  if (SchemaAST.isUnion(ast) === true) {
127
128
  return ast.types.some((type) => hasNull(type))
128
129
  }
@@ -130,7 +131,7 @@ const hasNull = (ast: SchemaAST.AST): boolean => {
130
131
  }
131
132
 
132
133
  const hasUndefined = (ast: SchemaAST.AST): boolean => {
133
- if (SchemaAST.isUndefinedKeyword(ast) === true) return true
134
+ if (SchemaAST.isUndefined(ast) === true) return true
134
135
  if (SchemaAST.isUnion(ast) === true) {
135
136
  return ast.types.some((type) => hasUndefined(type))
136
137
  }
@@ -152,36 +153,49 @@ const getColumnForType = (columnType: string, nullable = false): SqliteDsl.Colum
152
153
  }
153
154
  }
154
155
 
155
- const getColumnForSchema = (schema: Schema.Schema.AnyNoContext, nullable = false): SqliteDsl.ColumnDefinition.Any => {
156
+ const getColumnForSchema = (schema: Schema.Top, nullable = false): SqliteDsl.ColumnDefinition.Any => {
156
157
  const ast = schema.ast
157
158
  // Strip nullable wrapper to get core type
158
159
  const coreAst = stripNullable(ast)
159
- const coreSchema = stripNullable(ast) === ast ? schema : Schema.make(coreAst)
160
+ const coreSchema = (stripNullable(ast) === ast ? schema : Schema.make(coreAst)) as Schema.Codec<any, any>
160
161
 
161
162
  // Special case: Boolean is transformed to integer in SQLite
162
- if (SchemaAST.isBooleanKeyword(coreAst) === true) {
163
+ if (SchemaAST.isBoolean(coreAst) === true) {
163
164
  return SqliteDsl.boolean({ nullable })
164
165
  }
165
166
 
166
167
  // Get the encoded AST - what actually gets stored in SQLite
167
- const encodedAst = Schema.encodedSchema(coreSchema).ast
168
+ const encodedAst = Schema.toEncoded(coreSchema).ast
169
+
170
+ // Adapt Date values on the encoded side to ISO text, then run the original
171
+ // codec so its checks and transformations are preserved in both directions.
172
+ if (hasDateRepresentation(stripNullable(encodedAst)) === true) {
173
+ const encodedNullable = hasNull(encodedAst)
174
+ const dateStorage = encodedNullable === true ? Schema.NullOr(Schema.DateFromString) : Schema.DateFromString
175
+ const adaptedSchema = dateStorage.pipe(Schema.decodeTo(coreSchema))
176
+ return {
177
+ ...SqliteDsl.text(),
178
+ schema: nullable === true ? Schema.NullOr(adaptedSchema) : adaptedSchema,
179
+ // Encoded nulls may decode to non-null values, so allow SQL NULL without
180
+ // bypassing the original codec's null transformation.
181
+ nullable: nullable === true || encodedNullable === true,
182
+ }
183
+ }
168
184
 
169
185
  // Check if the encoded type matches SQLite native types
170
- if (SchemaAST.isStringKeyword(encodedAst) === true) {
186
+ if (SchemaAST.isString(encodedAst) === true) {
171
187
  return SqliteDsl.text({ schema: coreSchema, nullable })
172
188
  }
173
189
 
174
- if (SchemaAST.isNumberKeyword(encodedAst) === true) {
175
- // Special cases for integer columns
176
- const id = SchemaAST.getIdentifierAnnotation(coreAst).pipe(Option.getOrElse(() => ''))
177
- if (id === 'Int' || id === 'DateFromNumber') {
190
+ if (SchemaAST.isNumber(encodedAst) === true) {
191
+ if (hasCheck(coreAst.checks, 'effect/schema/isInt') === true || hasDateRepresentation(coreAst) === true) {
178
192
  return SqliteDsl.integer({ schema: coreSchema, nullable })
179
193
  }
180
194
  return SqliteDsl.real({ schema: coreSchema, nullable })
181
195
  }
182
196
 
183
197
  if (isUint8ArraySchema(coreAst) === true || isUint8ArraySchema(encodedAst) === true) {
184
- return SqliteDsl.blob({ schema: Schema.Uint8ArrayFromSelf as Schema.Schema<Uint8Array<ArrayBuffer>>, nullable })
198
+ return SqliteDsl.blob({ schema: coreSchema, nullable })
185
199
  }
186
200
 
187
201
  const literalColumn = getLiteralColumnDefinition(encodedAst, coreSchema, nullable, coreAst)
@@ -200,7 +214,7 @@ const stripNullable = (ast: SchemaAST.AST): SchemaAST.AST => {
200
214
 
201
215
  // Filter out null/undefined members while preserving any annotations on the union
202
216
  const coreTypes = ast.types.filter(
203
- (type) => !(SchemaAST.isLiteral(type) && type.literal === null) && !SchemaAST.isUndefinedKeyword(type),
217
+ (type) => SchemaAST.isNull(type) === false && SchemaAST.isUndefined(type) === false,
204
218
  )
205
219
 
206
220
  if (coreTypes.length === 0 || coreTypes.length === ast.types.length) {
@@ -211,12 +225,12 @@ const stripNullable = (ast: SchemaAST.AST): SchemaAST.AST => {
211
225
  return coreTypes[0]!
212
226
  }
213
227
 
214
- return SchemaAST.Union.make(coreTypes, ast.annotations)
228
+ return new SchemaAST.Union(coreTypes, ast.options, ast.annotations)
215
229
  }
216
230
 
217
231
  const getLiteralColumnDefinition = (
218
232
  ast: SchemaAST.AST,
219
- schema: Schema.Schema.AnyNoContext,
233
+ schema: Schema.Codec<any, any>,
220
234
  nullable: boolean,
221
235
  sourceAst: SchemaAST.AST,
222
236
  ): SqliteDsl.ColumnDefinition.Any | null => {
@@ -228,8 +242,7 @@ const getLiteralColumnDefinition = (
228
242
  case 'string':
229
243
  return SqliteDsl.text({ schema, nullable })
230
244
  case 'number': {
231
- const id = SchemaAST.getIdentifierAnnotation(sourceAst).pipe(Option.getOrElse(() => ''))
232
- if (id === 'Int' || id === 'DateFromNumber') {
245
+ if (hasCheck(sourceAst.checks, 'effect/schema/isInt') === true || hasDateRepresentation(sourceAst) === true) {
233
246
  return SqliteDsl.integer({ schema, nullable })
234
247
  }
235
248
 
@@ -247,6 +260,9 @@ const getLiteralColumnDefinition = (
247
260
  }
248
261
  }
249
262
 
263
+ /** Effect's built-in date codecs expose their semantic type through the Date representation annotation. */
264
+ const hasDateRepresentation = (ast: SchemaAST.AST): boolean => hasRepresentation(ast, 'effect/schema/Date')
265
+
250
266
  const extractLiteralValues = (ast: SchemaAST.AST): ReadonlyArray<SchemaAST.LiteralValue> | null => {
251
267
  if (SchemaAST.isLiteral(ast) === true) return [ast.literal]
252
268
 
@@ -255,7 +271,7 @@ const extractLiteralValues = (ast: SchemaAST.AST): ReadonlyArray<SchemaAST.Liter
255
271
  ast.types.length > 0 &&
256
272
  ast.types.every((type) => SchemaAST.isLiteral(type)) === true
257
273
  ) {
258
- return ast.types.map((type) => (type as SchemaAST.Literal).literal)
274
+ return ast.types.map((type) => type.literal)
259
275
  }
260
276
 
261
277
  return null
@@ -264,7 +280,7 @@ const extractLiteralValues = (ast: SchemaAST.AST): ReadonlyArray<SchemaAST.Liter
264
280
  const getLiteralValueType = (
265
281
  literals: ReadonlyArray<SchemaAST.LiteralValue>,
266
282
  ): 'string' | 'number' | 'boolean' | 'bigint' | null => {
267
- const literalTypes = new Set(literals.map((value) => (value === null ? 'null' : typeof value)))
283
+ const literalTypes = new Set(literals.map((value) => typeof value))
268
284
  if (literalTypes.size !== 1) return null
269
285
 
270
286
  const [literalType] = literalTypes
@@ -273,15 +289,49 @@ const getLiteralValueType = (
273
289
  : null
274
290
  }
275
291
 
292
+ /**
293
+ * Recursively checks for Effect built-in check metadata.
294
+ *
295
+ * Checks can be attached directly as `Filter`s or nested in `FilterGroup`s when
296
+ * schemas compose multiple refinements, e.g. `Schema.Int.check(...)`.
297
+ *
298
+ * Effect rc.109 replaced the closed `meta` annotation with the open `representation`
299
+ * identity, so built-in checks are matched by their representation id.
300
+ */
301
+ const hasCheck = (checks: ReadonlyArray<SchemaAST.Check<unknown>> | undefined, representationId: string): boolean => {
302
+ return (
303
+ checks?.some((check) => {
304
+ switch (check._tag) {
305
+ case 'Filter':
306
+ return check.annotations?.representation?.id === representationId
307
+ case 'FilterGroup':
308
+ return hasCheck(check.checks, representationId)
309
+ }
310
+ }) === true
311
+ )
312
+ }
313
+
276
314
  const isUint8ArraySchema = (ast: SchemaAST.AST): boolean => {
277
- const identifier = SchemaAST.getIdentifierAnnotation(ast)
278
- if (Option.isSome(identifier) === true && identifier.value.includes('Uint8Array') === true) {
315
+ // `resolveAt` reads the last check's annotations, which can mask the declaration's representation.
316
+ if (hasRepresentation(ast, 'effect/schema/Uint8Array') === true) {
317
+ return true
318
+ }
319
+
320
+ const identifier = SchemaAST.resolveIdentifier(ast)
321
+ if (identifier !== undefined && identifier.includes('Uint8Array') === true) {
279
322
  return true
280
323
  }
281
324
 
282
- if (SchemaAST.isTupleType(ast) === true) {
283
- return ast.elements.length === 0 && ast.rest.length === 1 && SchemaAST.isNumberKeyword(ast.rest[0]!.type)
325
+ if (SchemaAST.isArrays(ast) === true) {
326
+ return ast.elements.length === 0 && ast.rest.length === 1 && SchemaAST.isNumber(ast.rest[0]!)
284
327
  }
285
328
 
286
329
  return false
287
330
  }
331
+
332
+ const hasRepresentation = (ast: SchemaAST.AST, id: string): boolean => {
333
+ const representation = ast.annotations?.representation
334
+ return (
335
+ typeof representation === 'object' && representation !== null && 'id' in representation && representation.id === id
336
+ )
337
+ }
@@ -28,9 +28,9 @@ const createColumn = (
28
28
  case 'text':
29
29
  return Schema.String
30
30
  case 'integer':
31
- return options.defaultValue === true || options.defaultValue === false ? Schema.Boolean : Schema.Number
31
+ return options.defaultValue === true || options.defaultValue === false ? Schema.Boolean : Schema.Finite
32
32
  case 'real':
33
- return Schema.Number
33
+ return Schema.Finite
34
34
  case 'blob':
35
35
  return Schema.Uint8ArrayFromBase64
36
36
  default:
@@ -19,7 +19,7 @@ export const makeColumnSpec = (tableAst: SqliteAst.Table) => {
19
19
  // is only valid on a single column declared as INTEGER PRIMARY KEY (column-level).
20
20
  const columnDefStrs = tableAst.columns.map((column) =>
21
21
  toSqliteColumnSpec(column, {
22
- inlinePrimaryKey: hasSinglePk && column === pkColumn && column.primaryKey,
22
+ inlinePrimaryKey: hasSinglePk && column === pkColumn && column.primaryKey,
23
23
  }),
24
24
  )
25
25
 
@@ -40,7 +40,8 @@ const toSqliteColumnSpec = (column: SqliteAst.Column, opts: { inlinePrimaryKey:
40
40
  const nullableStr = opts.inlinePrimaryKey === true ? '' : column.nullable === false ? 'not null' : ''
41
41
 
42
42
  // Only include AUTOINCREMENT when it's valid: single-column INTEGER PRIMARY KEY
43
- const includeAutoIncrement = opts.inlinePrimaryKey === true && column.type._tag === 'integer' && column.autoIncrement === true
43
+ const includeAutoIncrement =
44
+ opts.inlinePrimaryKey === true && column.type._tag === 'integer' && column.autoIncrement === true
44
45
 
45
46
  const pkStr = opts.inlinePrimaryKey === true ? 'primary key' : ''
46
47
  const autoIncrementStr = includeAutoIncrement === true ? 'autoincrement' : ''
@@ -0,0 +1,6 @@
1
+ import { sha256 } from '@noble/hashes/sha2.js'
2
+
3
+ import { Base64Url } from '@livestore/utils/effect'
4
+
5
+ /** Preserve every digest bit while staying inside the 56-character SQLite VFS filename limit. */
6
+ export const digestToFingerprint = (bytes: Uint8Array): string => Base64Url.encode(sha256(bytes))
@@ -0,0 +1,209 @@
1
+ import { describe, expect, test } from 'vitest'
2
+
3
+ import { Schema } from '@livestore/utils/effect'
4
+
5
+ import { liveStoreStorageFormatVersion } from '../../../../../version.ts'
6
+ import { makeState } from '../../mod.ts'
7
+ import { REBUILD_META_TABLE } from '../../system-tables/state-tables.ts'
8
+ import { SqliteDsl } from '../mod.ts'
9
+ import { digestToFingerprint } from './fingerprint-digest.ts'
10
+ import { fingerprint } from './fingerprint.ts'
11
+
12
+ describe('SQLite storage fingerprints', () => {
13
+ test('pins the final fingerprint output', () => {
14
+ expect(fingerprint(makePhysicalTable().ast)).toBe('UnLwYzVBhwzPCK5q7TrPU3q2N0dTe8m_98bud8HsAs8')
15
+ expect(fingerprint(makeJsonTable('documents', representativeJsonSchema).ast)).toBe(
16
+ 'kUzaurzV2rcXYLljHOZ64TDR9c_RebqD7y5ZUM_nPBE',
17
+ )
18
+ expect(fingerprint(makeJsonTable('documents', normalizedCheckIdsJsonSchema).ast)).toBe(
19
+ 'I0XYuOUSYqWwG5Opxbc1u-TNNE3pFQCHzpBZ_ChYGaA',
20
+ )
21
+ expect(makeState({ tables: [], materializers: {} }).sqlite.hash).toBe('o8mmnRDnhXhkgDpBybM3FK7S-PkaLEj_pKcnbzgg3TU')
22
+ })
23
+
24
+ test('isolates pre-completion-marker state databases without changing the hash algorithm', () => {
25
+ const state = makeState({ tables: [], materializers: {} })
26
+ const legacyTables = [...state.sqlite.tables.values()]
27
+ .filter((table) => table.sqliteDef.name !== REBUILD_META_TABLE)
28
+ .map((table) => table.sqliteDef.ast)
29
+ const legacyHash = fingerprint({ _tag: 'dbSchema', tables: legacyTables })
30
+ expect(legacyHash).toBe('H5Uktp6Ffp84WDj_RWPnfDnaQEu_E61AMl7ieZ9Zn8k')
31
+ expect(state.sqlite.hash).not.toBe(legacyHash)
32
+ })
33
+
34
+ test('matches the standard SHA-256 vector', () => {
35
+ expect(digestToFingerprint(new TextEncoder().encode('abc'))).toBe('ungWv48Bz-pBQUDeXa4iI7ADYaOWF3qctBD_YfIAFa0')
36
+ })
37
+
38
+ test('keeps the full digest inside the Cloudflare VFS filename limit', () => {
39
+ const value = fingerprint(makePhysicalTable().ast)
40
+
41
+ expect(value).toHaveLength(43)
42
+ expect(`state${value}@${liveStoreStorageFormatVersion}.db`.length).toBeLessThanOrEqual(56)
43
+ })
44
+
45
+ test('is independent of table and index declaration order', () => {
46
+ const first = makeJsonTable('first', Schema.Struct({ value: Schema.String }))
47
+ const second = makeJsonTable('second', Schema.Struct({ value: Schema.Finite }))
48
+
49
+ expect(fingerprint({ _tag: 'dbSchema', tables: [first.ast, second.ast] })).toBe(
50
+ fingerprint({ _tag: 'dbSchema', tables: [second.ast, first.ast] }),
51
+ )
52
+
53
+ const table = SqliteDsl.table(
54
+ 'indexed',
55
+ {
56
+ id: SqliteDsl.text({ primaryKey: true }),
57
+ age: SqliteDsl.integer(),
58
+ },
59
+ [
60
+ { name: 'indexed_by_age', columns: ['age'], isUnique: false },
61
+ { name: 'indexed_by_id', columns: ['id'], isUnique: true },
62
+ ],
63
+ ).ast
64
+ expect(fingerprint({ ...table, indexes: table.indexes.toReversed() })).toBe(fingerprint(table))
65
+ })
66
+
67
+ test('ignores Effect metadata that does not affect accepted encoded JSON', () => {
68
+ const plain = makeJsonTable('documents', Schema.Struct({ value: Schema.String }))
69
+ const annotated = makeJsonTable(
70
+ 'documents',
71
+ Schema.Struct({ value: Schema.String }).annotate({ description: 'documentation only', title: 'Document' }),
72
+ )
73
+ const readonlyArray = makeJsonTable('documents', Schema.Array(Schema.String))
74
+ const mutableArray = makeJsonTable('documents', Schema.mutable(Schema.Array(Schema.String)))
75
+
76
+ expect(fingerprint(plain.ast)).toBe(fingerprint(annotated.ast))
77
+ expect(fingerprint(readonlyArray.ast)).toBe(fingerprint(mutableArray.ast))
78
+ })
79
+
80
+ test('changes when represented JSON checks change', () => {
81
+ const minimumTwo = makeJsonTable('documents', Schema.Struct({ value: Schema.String.check(Schema.isMinLength(2)) }))
82
+ const minimumThree = makeJsonTable(
83
+ 'documents',
84
+ Schema.Struct({ value: Schema.String.check(Schema.isMinLength(3)) }),
85
+ )
86
+
87
+ expect(fingerprint(minimumTwo.ast)).not.toBe(fingerprint(minimumThree.ast))
88
+ })
89
+
90
+ test('distinguishes codecs with the same encoded primitive', () => {
91
+ const date = makeJsonTable('documents', Schema.Struct({ value: Schema.DateFromString }))
92
+ const string = makeJsonTable('documents', Schema.Struct({ value: Schema.String }))
93
+
94
+ expect(fingerprint(date.ast)).not.toBe(fingerprint(string.ast))
95
+ })
96
+
97
+ test('handles recursive JSON schemas deterministically', () => {
98
+ const first = makeJsonTable('trees', makeTreeSchema())
99
+ const second = makeJsonTable('trees', makeTreeSchema())
100
+
101
+ expect(fingerprint(first.ast)).toBe(fingerprint(second.ast))
102
+ })
103
+
104
+ test('supports opaque Effect schemas without persistence annotations', () => {
105
+ const OpaqueString = Schema.declare<string>((value): value is string => typeof value === 'string')
106
+ const table = makeJsonTable('opaque_documents', Schema.Struct({ value: OpaqueString }))
107
+
108
+ expect(() => fingerprint(table.ast)).not.toThrow()
109
+ })
110
+
111
+ test('keeps application-owned representation payload fields', () => {
112
+ const first = Schema.declare<string>((value): value is string => typeof value === 'string', {
113
+ representation: { id: 'example/opaque', payload: { annotations: 'first', isMutable: true } },
114
+ })
115
+ const second = Schema.declare<string>((value): value is string => typeof value === 'string', {
116
+ representation: { id: 'example/opaque', payload: { annotations: 'second', isMutable: true } },
117
+ })
118
+
119
+ expect(fingerprint(makeJsonTable('documents', first).ast)).not.toBe(
120
+ fingerprint(makeJsonTable('documents', second).ast),
121
+ )
122
+ })
123
+
124
+ test('tracks JSON codecs passed through the generic text column API', () => {
125
+ const first = SqliteDsl.table('documents', {
126
+ value: SqliteDsl.text({ schema: Schema.fromJsonString(Schema.Struct({ value: Schema.String })) }),
127
+ })
128
+ const second = SqliteDsl.table('documents', {
129
+ value: SqliteDsl.text({ schema: Schema.fromJsonString(Schema.Struct({ value: Schema.Finite })) }),
130
+ })
131
+
132
+ expect(fingerprint(first.ast)).not.toBe(fingerprint(second.ast))
133
+ })
134
+
135
+ test('gives equivalent JSON DSL forms the same fingerprint', () => {
136
+ const valueSchema = Schema.Struct({ value: Schema.String })
137
+ const specialized = SqliteDsl.table('documents', {
138
+ value: SqliteDsl.json({ schema: valueSchema }),
139
+ })
140
+ const generic = SqliteDsl.table('documents', {
141
+ value: SqliteDsl.text({ schema: Schema.fromJsonString(valueSchema) }),
142
+ })
143
+
144
+ expect(fingerprint(specialized.ast)).toBe(fingerprint(generic.ast))
145
+ })
146
+
147
+ test('classifies physical defaults without hashing function source text', () => {
148
+ const none = SqliteDsl.text()
149
+ const firstThunk = SqliteDsl.text({ default: () => 'first' })
150
+ const secondThunk = SqliteDsl.text({ default: () => 'second' })
151
+ const literal = SqliteDsl.text({ default: 'first' })
152
+ const toTable = (definition: SqliteDsl.ColumnDefinition.Any) =>
153
+ SqliteDsl.table('defaults', { value: definition }).ast
154
+
155
+ expect(fingerprint(toTable(firstThunk))).toBe(fingerprint(toTable(secondThunk)))
156
+ expect(fingerprint(toTable(firstThunk))).not.toBe(fingerprint(toTable(none)))
157
+ expect(fingerprint(toTable(literal))).not.toBe(fingerprint(toTable(firstThunk)))
158
+ })
159
+ })
160
+
161
+ const makePhysicalTable = () =>
162
+ SqliteDsl.table(
163
+ 'users',
164
+ {
165
+ id: SqliteDsl.text({ primaryKey: true }),
166
+ age: SqliteDsl.integer({ nullable: true }),
167
+ },
168
+ [{ name: 'users_by_age', columns: ['age'], isUnique: false }],
169
+ )
170
+
171
+ const makeJsonTable = (name: string, schema: Schema.Codec<unknown, unknown>) =>
172
+ SqliteDsl.table(name, {
173
+ id: SqliteDsl.text({ primaryKey: true }),
174
+ value: SqliteDsl.json({ schema }),
175
+ })
176
+
177
+ const representativeJsonSchema = Schema.Struct({
178
+ title: Schema.String.check(Schema.isMinLength(1)),
179
+ tags: Schema.Array(Schema.String),
180
+ status: Schema.Union([Schema.Literal('draft'), Schema.Literal('published')]),
181
+ publishedAt: Schema.NullOr(Schema.DateFromString),
182
+ metadata: Schema.Record(Schema.String, Schema.Json),
183
+ })
184
+
185
+ /** Uses the JSON-compatible checks whose representation ids the fingerprint normalizes. */
186
+ const normalizedCheckIdsJsonSchema = Schema.Struct({
187
+ slug: Schema.String.check(
188
+ Schema.isBetweenLength(1, 64),
189
+ Schema.isStartingWith('a'),
190
+ Schema.isEndingWith('z'),
191
+ Schema.isIncluding('-'),
192
+ ),
193
+ tags: Schema.Array(Schema.String).check(Schema.isBetweenLength(0, 10)),
194
+ initial: Schema.Char,
195
+ labels: Schema.Record(Schema.String, Schema.String).check(Schema.isBetweenProperties(0, 5)),
196
+ })
197
+
198
+ interface TreeNode {
199
+ readonly value: string
200
+ readonly children: ReadonlyArray<TreeNode>
201
+ }
202
+
203
+ const makeTreeSchema = (): Schema.Codec<TreeNode> => {
204
+ const TreeNode: Schema.Codec<TreeNode> = Schema.Struct({
205
+ value: Schema.String,
206
+ children: Schema.Array(Schema.suspend(() => TreeNode)),
207
+ })
208
+ return TreeNode
209
+ }