@livestore/common 0.4.0-dev.9 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (513) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/ClientSessionLeaderThreadProxy.d.ts +27 -12
  3. package/dist/ClientSessionLeaderThreadProxy.d.ts.map +1 -1
  4. package/dist/ClientSessionLeaderThreadProxy.js.map +1 -1
  5. package/dist/WorkerTransportError.d.ts +11 -0
  6. package/dist/WorkerTransportError.d.ts.map +1 -0
  7. package/dist/WorkerTransportError.js +11 -0
  8. package/dist/WorkerTransportError.js.map +1 -0
  9. package/dist/adapter-types.d.ts +37 -7
  10. package/dist/adapter-types.d.ts.map +1 -1
  11. package/dist/adapter-types.js +27 -1
  12. package/dist/adapter-types.js.map +1 -1
  13. package/dist/bounded-collections.d.ts.map +1 -1
  14. package/dist/bounded-collections.js +6 -4
  15. package/dist/bounded-collections.js.map +1 -1
  16. package/dist/debug-info.d.ts.map +1 -1
  17. package/dist/debug-info.js +33 -6
  18. package/dist/debug-info.js.map +1 -1
  19. package/dist/devtools/devtools-compatibility.test.d.ts +2 -0
  20. package/dist/devtools/devtools-compatibility.test.d.ts.map +1 -0
  21. package/dist/devtools/devtools-compatibility.test.js +15 -0
  22. package/dist/devtools/devtools-compatibility.test.js.map +1 -0
  23. package/dist/devtools/devtools-messages-client-session.d.ts +55 -24
  24. package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -1
  25. package/dist/devtools/devtools-messages-client-session.js +22 -5
  26. package/dist/devtools/devtools-messages-client-session.js.map +1 -1
  27. package/dist/devtools/devtools-messages-common.d.ts +11 -14
  28. package/dist/devtools/devtools-messages-common.d.ts.map +1 -1
  29. package/dist/devtools/devtools-messages-common.js +7 -9
  30. package/dist/devtools/devtools-messages-common.js.map +1 -1
  31. package/dist/devtools/devtools-messages-leader.d.ts +65 -30
  32. package/dist/devtools/devtools-messages-leader.d.ts.map +1 -1
  33. package/dist/devtools/devtools-messages-leader.js +29 -11
  34. package/dist/devtools/devtools-messages-leader.js.map +1 -1
  35. package/dist/devtools/devtools-sessioninfo.d.ts +14 -2
  36. package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -1
  37. package/dist/devtools/devtools-sessioninfo.js +7 -4
  38. package/dist/devtools/devtools-sessioninfo.js.map +1 -1
  39. package/dist/devtools/mod.d.ts +13 -2
  40. package/dist/devtools/mod.d.ts.map +1 -1
  41. package/dist/devtools/mod.js +10 -3
  42. package/dist/devtools/mod.js.map +1 -1
  43. package/dist/errors.d.ts +48 -18
  44. package/dist/errors.d.ts.map +1 -1
  45. package/dist/errors.js +20 -12
  46. package/dist/errors.js.map +1 -1
  47. package/dist/index.d.ts +4 -1
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +4 -1
  50. package/dist/index.js.map +1 -1
  51. package/dist/leader-thread/LeaderSyncProcessor.d.ts +53 -6
  52. package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
  53. package/dist/leader-thread/LeaderSyncProcessor.js +325 -257
  54. package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
  55. package/dist/leader-thread/RejectedPushError.d.ts +107 -0
  56. package/dist/leader-thread/RejectedPushError.d.ts.map +1 -0
  57. package/dist/leader-thread/RejectedPushError.js +78 -0
  58. package/dist/leader-thread/RejectedPushError.js.map +1 -0
  59. package/dist/leader-thread/connection.js +1 -1
  60. package/dist/leader-thread/connection.js.map +1 -1
  61. package/dist/leader-thread/eventlog.d.ts +19 -14
  62. package/dist/leader-thread/eventlog.d.ts.map +1 -1
  63. package/dist/leader-thread/eventlog.js +78 -18
  64. package/dist/leader-thread/eventlog.js.map +1 -1
  65. package/dist/leader-thread/leader-worker-devtools.d.ts +1 -2
  66. package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
  67. package/dist/leader-thread/leader-worker-devtools.js +90 -58
  68. package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
  69. package/dist/leader-thread/make-leader-thread-layer.d.ts +15 -7
  70. package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
  71. package/dist/leader-thread/make-leader-thread-layer.js +49 -17
  72. package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
  73. package/dist/leader-thread/make-leader-thread-layer.test.d.ts +2 -0
  74. package/dist/leader-thread/make-leader-thread-layer.test.d.ts.map +1 -0
  75. package/dist/leader-thread/make-leader-thread-layer.test.js +32 -0
  76. package/dist/leader-thread/make-leader-thread-layer.test.js.map +1 -0
  77. package/dist/leader-thread/materialize-event.d.ts +1 -1
  78. package/dist/leader-thread/materialize-event.d.ts.map +1 -1
  79. package/dist/leader-thread/materialize-event.js +28 -9
  80. package/dist/leader-thread/materialize-event.js.map +1 -1
  81. package/dist/leader-thread/mod.d.ts +1 -0
  82. package/dist/leader-thread/mod.d.ts.map +1 -1
  83. package/dist/leader-thread/mod.js +1 -0
  84. package/dist/leader-thread/mod.js.map +1 -1
  85. package/dist/leader-thread/recreate-db.d.ts +2 -2
  86. package/dist/leader-thread/recreate-db.d.ts.map +1 -1
  87. package/dist/leader-thread/recreate-db.js +6 -6
  88. package/dist/leader-thread/recreate-db.js.map +1 -1
  89. package/dist/leader-thread/shutdown-channel.d.ts +2 -2
  90. package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
  91. package/dist/leader-thread/shutdown-channel.js +2 -2
  92. package/dist/leader-thread/shutdown-channel.js.map +1 -1
  93. package/dist/leader-thread/stream-events.d.ts +56 -0
  94. package/dist/leader-thread/stream-events.d.ts.map +1 -0
  95. package/dist/leader-thread/stream-events.js +167 -0
  96. package/dist/leader-thread/stream-events.js.map +1 -0
  97. package/dist/leader-thread/types.d.ts +95 -17
  98. package/dist/leader-thread/types.d.ts.map +1 -1
  99. package/dist/leader-thread/types.js +13 -0
  100. package/dist/leader-thread/types.js.map +1 -1
  101. package/dist/logging.d.ts +40 -0
  102. package/dist/logging.d.ts.map +1 -0
  103. package/dist/logging.js +33 -0
  104. package/dist/logging.js.map +1 -0
  105. package/dist/make-client-session.d.ts +5 -3
  106. package/dist/make-client-session.d.ts.map +1 -1
  107. package/dist/make-client-session.js +7 -4
  108. package/dist/make-client-session.js.map +1 -1
  109. package/dist/materializer-helper.d.ts +6 -6
  110. package/dist/materializer-helper.d.ts.map +1 -1
  111. package/dist/materializer-helper.js +18 -8
  112. package/dist/materializer-helper.js.map +1 -1
  113. package/dist/otel.d.ts +2 -1
  114. package/dist/otel.d.ts.map +1 -1
  115. package/dist/otel.js +7 -2
  116. package/dist/otel.js.map +1 -1
  117. package/dist/rematerialize-from-eventlog.d.ts +3 -3
  118. package/dist/rematerialize-from-eventlog.d.ts.map +1 -1
  119. package/dist/rematerialize-from-eventlog.js +40 -29
  120. package/dist/rematerialize-from-eventlog.js.map +1 -1
  121. package/dist/schema/EventDef/define.d.ts +161 -0
  122. package/dist/schema/EventDef/define.d.ts.map +1 -0
  123. package/dist/schema/EventDef/define.js +140 -0
  124. package/dist/schema/EventDef/define.js.map +1 -0
  125. package/dist/schema/EventDef/deprecated.d.ts +99 -0
  126. package/dist/schema/EventDef/deprecated.d.ts.map +1 -0
  127. package/dist/schema/EventDef/deprecated.js +144 -0
  128. package/dist/schema/EventDef/deprecated.js.map +1 -0
  129. package/dist/schema/EventDef/deprecated.test.d.ts +2 -0
  130. package/dist/schema/EventDef/deprecated.test.d.ts.map +1 -0
  131. package/dist/schema/EventDef/deprecated.test.js +95 -0
  132. package/dist/schema/EventDef/deprecated.test.js.map +1 -0
  133. package/dist/schema/EventDef/event-def.d.ts +110 -0
  134. package/dist/schema/EventDef/event-def.d.ts.map +1 -0
  135. package/dist/schema/EventDef/event-def.js +2 -0
  136. package/dist/schema/EventDef/event-def.js.map +1 -0
  137. package/dist/schema/EventDef/facts.d.ts +118 -0
  138. package/dist/schema/EventDef/facts.d.ts.map +1 -0
  139. package/dist/schema/EventDef/facts.js +53 -0
  140. package/dist/schema/EventDef/facts.js.map +1 -0
  141. package/dist/schema/EventDef/materializer.d.ts +155 -0
  142. package/dist/schema/EventDef/materializer.d.ts.map +1 -0
  143. package/dist/schema/EventDef/materializer.js +83 -0
  144. package/dist/schema/EventDef/materializer.js.map +1 -0
  145. package/dist/schema/EventDef/mod.d.ts +6 -0
  146. package/dist/schema/EventDef/mod.d.ts.map +1 -0
  147. package/dist/schema/EventDef/mod.js +6 -0
  148. package/dist/schema/EventDef/mod.js.map +1 -0
  149. package/dist/schema/EventSequenceNumber/client.d.ts +136 -0
  150. package/dist/schema/EventSequenceNumber/client.d.ts.map +1 -0
  151. package/dist/schema/EventSequenceNumber/client.js +193 -0
  152. package/dist/schema/EventSequenceNumber/client.js.map +1 -0
  153. package/dist/schema/EventSequenceNumber/global.d.ts +15 -0
  154. package/dist/schema/EventSequenceNumber/global.d.ts.map +1 -0
  155. package/dist/schema/EventSequenceNumber/global.js +14 -0
  156. package/dist/schema/EventSequenceNumber/global.js.map +1 -0
  157. package/dist/schema/EventSequenceNumber/mod.d.ts +37 -0
  158. package/dist/schema/EventSequenceNumber/mod.d.ts.map +1 -0
  159. package/dist/schema/EventSequenceNumber/mod.js +37 -0
  160. package/dist/schema/EventSequenceNumber/mod.js.map +1 -0
  161. package/dist/schema/EventSequenceNumber.test.js +44 -44
  162. package/dist/schema/EventSequenceNumber.test.js.map +1 -1
  163. package/dist/schema/{LiveStoreEvent.d.ts → LiveStoreEvent/client.d.ts} +102 -111
  164. package/dist/schema/LiveStoreEvent/client.d.ts.map +1 -0
  165. package/dist/schema/LiveStoreEvent/client.js +176 -0
  166. package/dist/schema/LiveStoreEvent/client.js.map +1 -0
  167. package/dist/schema/LiveStoreEvent/client.test.d.ts +2 -0
  168. package/dist/schema/LiveStoreEvent/client.test.d.ts.map +1 -0
  169. package/dist/schema/LiveStoreEvent/client.test.js +111 -0
  170. package/dist/schema/LiveStoreEvent/client.test.js.map +1 -0
  171. package/dist/schema/LiveStoreEvent/for-event-def.d.ts +52 -0
  172. package/dist/schema/LiveStoreEvent/for-event-def.d.ts.map +1 -0
  173. package/dist/schema/LiveStoreEvent/for-event-def.js +2 -0
  174. package/dist/schema/LiveStoreEvent/for-event-def.js.map +1 -0
  175. package/dist/schema/LiveStoreEvent/global.d.ts +36 -0
  176. package/dist/schema/LiveStoreEvent/global.d.ts.map +1 -0
  177. package/dist/schema/LiveStoreEvent/global.js +31 -0
  178. package/dist/schema/LiveStoreEvent/global.js.map +1 -0
  179. package/dist/schema/LiveStoreEvent/input.d.ts +46 -0
  180. package/dist/schema/LiveStoreEvent/input.d.ts.map +1 -0
  181. package/dist/schema/LiveStoreEvent/input.js +26 -0
  182. package/dist/schema/LiveStoreEvent/input.js.map +1 -0
  183. package/dist/schema/LiveStoreEvent/mod.d.ts +5 -0
  184. package/dist/schema/LiveStoreEvent/mod.d.ts.map +1 -0
  185. package/dist/schema/LiveStoreEvent/mod.js +5 -0
  186. package/dist/schema/LiveStoreEvent/mod.js.map +1 -0
  187. package/dist/schema/events.d.ts +1 -1
  188. package/dist/schema/events.d.ts.map +1 -1
  189. package/dist/schema/events.js +1 -1
  190. package/dist/schema/events.js.map +1 -1
  191. package/dist/schema/mod.d.ts +6 -4
  192. package/dist/schema/mod.d.ts.map +1 -1
  193. package/dist/schema/mod.js +5 -4
  194. package/dist/schema/mod.js.map +1 -1
  195. package/dist/schema/schema.d.ts +16 -1
  196. package/dist/schema/schema.d.ts.map +1 -1
  197. package/dist/schema/schema.js +32 -4
  198. package/dist/schema/schema.js.map +1 -1
  199. package/dist/schema/state/sqlite/client-document-def.d.ts +2 -1
  200. package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -1
  201. package/dist/schema/state/sqlite/client-document-def.js +36 -15
  202. package/dist/schema/state/sqlite/client-document-def.js.map +1 -1
  203. package/dist/schema/state/sqlite/client-document-def.test.js +121 -2
  204. package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -1
  205. package/dist/schema/state/sqlite/column-annotations.d.ts.map +1 -1
  206. package/dist/schema/state/sqlite/column-annotations.js +1 -1
  207. package/dist/schema/state/sqlite/column-annotations.js.map +1 -1
  208. package/dist/schema/state/sqlite/column-annotations.test.js +2 -2
  209. package/dist/schema/state/sqlite/column-annotations.test.js.map +1 -1
  210. package/dist/schema/state/sqlite/column-def.d.ts.map +1 -1
  211. package/dist/schema/state/sqlite/column-def.js +96 -47
  212. package/dist/schema/state/sqlite/column-def.js.map +1 -1
  213. package/dist/schema/state/sqlite/column-def.test.js +51 -12
  214. package/dist/schema/state/sqlite/column-def.test.js.map +1 -1
  215. package/dist/schema/state/sqlite/column-spec.d.ts.map +1 -1
  216. package/dist/schema/state/sqlite/column-spec.js +30 -12
  217. package/dist/schema/state/sqlite/column-spec.js.map +1 -1
  218. package/dist/schema/state/sqlite/column-spec.test.js +24 -15
  219. package/dist/schema/state/sqlite/column-spec.test.js.map +1 -1
  220. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js +2 -2
  221. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js.map +1 -1
  222. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts +16 -10
  223. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts.map +1 -1
  224. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js +15 -4
  225. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js.map +1 -1
  226. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js +1 -1
  227. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js.map +1 -1
  228. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts +1 -1
  229. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts.map +1 -1
  230. package/dist/schema/state/sqlite/db-schema/dsl/mod.js +1 -1
  231. package/dist/schema/state/sqlite/db-schema/dsl/mod.js.map +1 -1
  232. package/dist/schema/state/sqlite/mod.d.ts +2 -2
  233. package/dist/schema/state/sqlite/mod.d.ts.map +1 -1
  234. package/dist/schema/state/sqlite/mod.js +5 -7
  235. package/dist/schema/state/sqlite/mod.js.map +1 -1
  236. package/dist/schema/state/sqlite/query-builder/api.d.ts +51 -22
  237. package/dist/schema/state/sqlite/query-builder/api.d.ts.map +1 -1
  238. package/dist/schema/state/sqlite/query-builder/astToSql.d.ts.map +1 -1
  239. package/dist/schema/state/sqlite/query-builder/astToSql.js +99 -22
  240. package/dist/schema/state/sqlite/query-builder/astToSql.js.map +1 -1
  241. package/dist/schema/state/sqlite/query-builder/impl.d.ts +1 -1
  242. package/dist/schema/state/sqlite/query-builder/impl.d.ts.map +1 -1
  243. package/dist/schema/state/sqlite/query-builder/impl.js +28 -15
  244. package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -1
  245. package/dist/schema/state/sqlite/query-builder/impl.test.js +231 -93
  246. package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -1
  247. package/dist/schema/state/sqlite/schema-helpers.d.ts +2 -2
  248. package/dist/schema/state/sqlite/schema-helpers.d.ts.map +1 -1
  249. package/dist/schema/state/sqlite/schema-helpers.js +24 -14
  250. package/dist/schema/state/sqlite/schema-helpers.js.map +1 -1
  251. package/dist/schema/state/sqlite/schema-helpers.test.d.ts +2 -0
  252. package/dist/schema/state/sqlite/schema-helpers.test.d.ts.map +1 -0
  253. package/dist/schema/state/sqlite/schema-helpers.test.js +36 -0
  254. package/dist/schema/state/sqlite/schema-helpers.test.js.map +1 -0
  255. package/dist/schema/state/sqlite/{system-tables.d.ts → system-tables/eventlog-tables.d.ts} +21 -450
  256. package/dist/schema/state/sqlite/system-tables/eventlog-tables.d.ts.map +1 -0
  257. package/dist/schema/state/sqlite/system-tables/eventlog-tables.js +54 -0
  258. package/dist/schema/state/sqlite/system-tables/eventlog-tables.js.map +1 -0
  259. package/dist/schema/state/sqlite/system-tables/mod.d.ts +3 -0
  260. package/dist/schema/state/sqlite/system-tables/mod.d.ts.map +1 -0
  261. package/dist/schema/state/sqlite/system-tables/mod.js +3 -0
  262. package/dist/schema/state/sqlite/system-tables/mod.js.map +1 -0
  263. package/dist/schema/state/sqlite/system-tables/state-tables.d.ts +456 -0
  264. package/dist/schema/state/sqlite/system-tables/state-tables.d.ts.map +1 -0
  265. package/dist/schema/state/sqlite/system-tables/state-tables.js +55 -0
  266. package/dist/schema/state/sqlite/system-tables/state-tables.js.map +1 -0
  267. package/dist/schema/state/sqlite/table-def.d.ts +5 -3
  268. package/dist/schema/state/sqlite/table-def.d.ts.map +1 -1
  269. package/dist/schema/state/sqlite/table-def.js +1 -1
  270. package/dist/schema/state/sqlite/table-def.js.map +1 -1
  271. package/dist/schema/state/sqlite/table-def.test.js +92 -3
  272. package/dist/schema/state/sqlite/table-def.test.js.map +1 -1
  273. package/dist/schema/unknown-events.d.ts +47 -0
  274. package/dist/schema/unknown-events.d.ts.map +1 -0
  275. package/dist/schema/unknown-events.js +69 -0
  276. package/dist/schema/unknown-events.js.map +1 -0
  277. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.d.ts +2 -0
  278. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.d.ts.map +1 -0
  279. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js +73 -0
  280. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js.map +1 -0
  281. package/dist/schema-management/common.js +2 -2
  282. package/dist/schema-management/common.js.map +1 -1
  283. package/dist/schema-management/migrations.d.ts +32 -2
  284. package/dist/schema-management/migrations.d.ts.map +1 -1
  285. package/dist/schema-management/migrations.js +38 -6
  286. package/dist/schema-management/migrations.js.map +1 -1
  287. package/dist/schema-management/validate-schema.d.ts +3 -3
  288. package/dist/schema-management/validate-schema.d.ts.map +1 -1
  289. package/dist/schema-management/validate-schema.js +2 -2
  290. package/dist/schema-management/validate-schema.js.map +1 -1
  291. package/dist/sql-queries/sql-queries.d.ts.map +1 -1
  292. package/dist/sql-queries/sql-queries.js +18 -6
  293. package/dist/sql-queries/sql-queries.js.map +1 -1
  294. package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
  295. package/dist/sql-queries/sql-query-builder.js.map +1 -1
  296. package/dist/sqlite-db-helper.js +3 -3
  297. package/dist/sqlite-db-helper.js.map +1 -1
  298. package/dist/sqlite-types.d.ts +5 -5
  299. package/dist/sqlite-types.d.ts.map +1 -1
  300. package/dist/sqlite-types.js.map +1 -1
  301. package/dist/sync/ClientSessionSyncProcessor.d.ts +12 -12
  302. package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
  303. package/dist/sync/ClientSessionSyncProcessor.js +99 -114
  304. package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
  305. package/dist/sync/errors.d.ts +0 -33
  306. package/dist/sync/errors.d.ts.map +1 -1
  307. package/dist/sync/errors.js +5 -22
  308. package/dist/sync/errors.js.map +1 -1
  309. package/dist/sync/index.d.ts +2 -0
  310. package/dist/sync/index.d.ts.map +1 -1
  311. package/dist/sync/index.js +2 -0
  312. package/dist/sync/index.js.map +1 -1
  313. package/dist/sync/mock-sync-backend.d.ts +10 -8
  314. package/dist/sync/mock-sync-backend.d.ts.map +1 -1
  315. package/dist/sync/mock-sync-backend.js +71 -69
  316. package/dist/sync/mock-sync-backend.js.map +1 -1
  317. package/dist/sync/next/compact-events.d.ts.map +1 -1
  318. package/dist/sync/next/compact-events.js +11 -12
  319. package/dist/sync/next/compact-events.js.map +1 -1
  320. package/dist/sync/next/facts.d.ts +5 -5
  321. package/dist/sync/next/facts.d.ts.map +1 -1
  322. package/dist/sync/next/facts.js +7 -8
  323. package/dist/sync/next/facts.js.map +1 -1
  324. package/dist/sync/next/history-dag-common.d.ts +54 -15
  325. package/dist/sync/next/history-dag-common.d.ts.map +1 -1
  326. package/dist/sync/next/history-dag-common.js +198 -9
  327. package/dist/sync/next/history-dag-common.js.map +1 -1
  328. package/dist/sync/next/history-dag.d.ts.map +1 -1
  329. package/dist/sync/next/history-dag.js +11 -11
  330. package/dist/sync/next/history-dag.js.map +1 -1
  331. package/dist/sync/next/rebase-events.d.ts +5 -5
  332. package/dist/sync/next/rebase-events.d.ts.map +1 -1
  333. package/dist/sync/next/rebase-events.js +6 -6
  334. package/dist/sync/next/rebase-events.js.map +1 -1
  335. package/dist/sync/next/test/compact-events.calculator.test.js +2 -2
  336. package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
  337. package/dist/sync/next/test/compact-events.test.d.ts.map +1 -1
  338. package/dist/sync/next/test/compact-events.test.js +2 -2
  339. package/dist/sync/next/test/compact-events.test.js.map +1 -1
  340. package/dist/sync/next/test/event-fixtures.d.ts +2 -2
  341. package/dist/sync/next/test/event-fixtures.d.ts.map +1 -1
  342. package/dist/sync/next/test/event-fixtures.js +11 -11
  343. package/dist/sync/next/test/event-fixtures.js.map +1 -1
  344. package/dist/sync/sync-backend-kv.d.ts +3 -3
  345. package/dist/sync/sync-backend-kv.d.ts.map +1 -1
  346. package/dist/sync/sync-backend-kv.js +3 -3
  347. package/dist/sync/sync-backend-kv.js.map +1 -1
  348. package/dist/sync/sync-backend.d.ts +33 -13
  349. package/dist/sync/sync-backend.d.ts.map +1 -1
  350. package/dist/sync/sync-backend.js +38 -1
  351. package/dist/sync/sync-backend.js.map +1 -1
  352. package/dist/sync/sync.d.ts +23 -2
  353. package/dist/sync/sync.d.ts.map +1 -1
  354. package/dist/sync/syncstate.d.ts +55 -55
  355. package/dist/sync/syncstate.d.ts.map +1 -1
  356. package/dist/sync/syncstate.js +80 -98
  357. package/dist/sync/syncstate.js.map +1 -1
  358. package/dist/sync/syncstate.test.js +221 -132
  359. package/dist/sync/syncstate.test.js.map +1 -1
  360. package/dist/sync/transport-chunking.d.ts +36 -0
  361. package/dist/sync/transport-chunking.d.ts.map +1 -0
  362. package/dist/sync/transport-chunking.js +56 -0
  363. package/dist/sync/transport-chunking.js.map +1 -0
  364. package/dist/sync/validate-push-payload.d.ts +2 -2
  365. package/dist/sync/validate-push-payload.d.ts.map +1 -1
  366. package/dist/sync/validate-push-payload.js +4 -6
  367. package/dist/sync/validate-push-payload.js.map +1 -1
  368. package/dist/testing/event-factory.d.ts +3 -3
  369. package/dist/testing/event-factory.d.ts.map +1 -1
  370. package/dist/testing/event-factory.js +5 -7
  371. package/dist/testing/event-factory.js.map +1 -1
  372. package/dist/util.js +2 -2
  373. package/dist/util.js.map +1 -1
  374. package/dist/version.d.ts +24 -5
  375. package/dist/version.d.ts.map +1 -1
  376. package/dist/version.js +25 -8
  377. package/dist/version.js.map +1 -1
  378. package/package.json +67 -15
  379. package/src/ClientSessionLeaderThreadProxy.ts +27 -12
  380. package/src/WorkerTransportError.ts +12 -0
  381. package/src/adapter-types.ts +50 -7
  382. package/src/bounded-collections.ts +6 -5
  383. package/src/debug-info.ts +37 -6
  384. package/src/devtools/devtools-compatibility.test.ts +18 -0
  385. package/src/devtools/devtools-messages-client-session.ts +22 -4
  386. package/src/devtools/devtools-messages-common.ts +7 -12
  387. package/src/devtools/devtools-messages-leader.ts +29 -10
  388. package/src/devtools/devtools-sessioninfo.ts +8 -5
  389. package/src/devtools/mod.ts +11 -2
  390. package/src/errors.ts +32 -24
  391. package/src/index.ts +4 -1
  392. package/src/leader-thread/LeaderSyncProcessor.ts +523 -373
  393. package/src/leader-thread/RejectedPushError.ts +106 -0
  394. package/src/leader-thread/connection.ts +1 -1
  395. package/src/leader-thread/eventlog.ts +112 -39
  396. package/src/leader-thread/leader-worker-devtools.ts +201 -120
  397. package/src/leader-thread/make-leader-thread-layer.test.ts +44 -0
  398. package/src/leader-thread/make-leader-thread-layer.ts +125 -40
  399. package/src/leader-thread/materialize-event.ts +40 -10
  400. package/src/leader-thread/mod.ts +1 -0
  401. package/src/leader-thread/recreate-db.ts +7 -7
  402. package/src/leader-thread/shutdown-channel.ts +4 -8
  403. package/src/leader-thread/stream-events.ts +206 -0
  404. package/src/leader-thread/types.ts +68 -18
  405. package/src/logging.ts +62 -0
  406. package/src/make-client-session.ts +11 -5
  407. package/src/materializer-helper.ts +27 -16
  408. package/src/otel.ts +13 -2
  409. package/src/rematerialize-from-eventlog.ts +61 -51
  410. package/src/schema/EventDef/define.ts +217 -0
  411. package/src/schema/EventDef/deprecated.test.ts +129 -0
  412. package/src/schema/EventDef/deprecated.ts +175 -0
  413. package/src/schema/EventDef/event-def.ts +125 -0
  414. package/src/schema/EventDef/facts.ts +135 -0
  415. package/src/schema/EventDef/materializer.ts +172 -0
  416. package/src/schema/EventDef/mod.ts +5 -0
  417. package/src/schema/EventSequenceNumber/client.ts +257 -0
  418. package/src/schema/EventSequenceNumber/global.ts +19 -0
  419. package/src/schema/EventSequenceNumber/mod.ts +37 -0
  420. package/src/schema/EventSequenceNumber.test.ts +72 -53
  421. package/src/schema/LiveStoreEvent/client.test.ts +129 -0
  422. package/src/schema/LiveStoreEvent/client.ts +235 -0
  423. package/src/schema/LiveStoreEvent/for-event-def.ts +60 -0
  424. package/src/schema/LiveStoreEvent/global.ts +45 -0
  425. package/src/schema/LiveStoreEvent/input.ts +63 -0
  426. package/src/schema/LiveStoreEvent/mod.ts +4 -0
  427. package/src/schema/events.ts +1 -1
  428. package/src/schema/mod.ts +6 -4
  429. package/src/schema/schema.ts +46 -5
  430. package/src/schema/state/sqlite/client-document-def.test.ts +144 -5
  431. package/src/schema/state/sqlite/client-document-def.ts +47 -34
  432. package/src/schema/state/sqlite/column-annotations.test.ts +3 -2
  433. package/src/schema/state/sqlite/column-annotations.ts +2 -1
  434. package/src/schema/state/sqlite/column-def.test.ts +66 -12
  435. package/src/schema/state/sqlite/column-def.ts +119 -47
  436. package/src/schema/state/sqlite/column-spec.test.ts +32 -17
  437. package/src/schema/state/sqlite/column-spec.ts +37 -11
  438. package/src/schema/state/sqlite/db-schema/ast/sqlite.ts +2 -2
  439. package/src/schema/state/sqlite/db-schema/dsl/field-defs.test.ts +2 -1
  440. package/src/schema/state/sqlite/db-schema/dsl/field-defs.ts +41 -15
  441. package/src/schema/state/sqlite/db-schema/dsl/mod.ts +13 -19
  442. package/src/schema/state/sqlite/mod.ts +7 -8
  443. package/src/schema/state/sqlite/query-builder/api.ts +55 -17
  444. package/src/schema/state/sqlite/query-builder/astToSql.ts +110 -21
  445. package/src/schema/state/sqlite/query-builder/impl.test.ts +267 -93
  446. package/src/schema/state/sqlite/query-builder/impl.ts +26 -13
  447. package/src/schema/state/sqlite/schema-helpers.test.ts +44 -0
  448. package/src/schema/state/sqlite/schema-helpers.ts +30 -22
  449. package/src/schema/state/sqlite/system-tables/eventlog-tables.ts +64 -0
  450. package/src/schema/state/sqlite/system-tables/mod.ts +2 -0
  451. package/src/schema/state/sqlite/system-tables/state-tables.ts +69 -0
  452. package/src/schema/state/sqlite/table-def.test.ts +114 -3
  453. package/src/schema/state/sqlite/table-def.ts +16 -22
  454. package/src/schema/unknown-events.ts +131 -0
  455. package/src/schema-management/__tests__/migrations-autoincrement-quoting.test.ts +88 -0
  456. package/src/schema-management/common.ts +2 -2
  457. package/src/schema-management/migrations.ts +42 -9
  458. package/src/schema-management/validate-schema.ts +3 -3
  459. package/src/sql-queries/sql-queries.ts +18 -6
  460. package/src/sql-queries/sql-query-builder.ts +1 -0
  461. package/src/sqlite-db-helper.ts +3 -3
  462. package/src/sqlite-types.ts +6 -5
  463. package/src/sync/ClientSessionSyncProcessor.ts +152 -142
  464. package/src/sync/errors.ts +12 -24
  465. package/src/sync/index.ts +2 -0
  466. package/src/sync/mock-sync-backend.ts +146 -104
  467. package/src/sync/next/compact-events.ts +10 -11
  468. package/src/sync/next/facts.ts +13 -14
  469. package/src/sync/next/history-dag-common.ts +280 -26
  470. package/src/sync/next/history-dag.ts +17 -13
  471. package/src/sync/next/rebase-events.ts +12 -12
  472. package/src/sync/next/test/compact-events.calculator.test.ts +3 -2
  473. package/src/sync/next/test/compact-events.test.ts +4 -3
  474. package/src/sync/next/test/event-fixtures.ts +13 -13
  475. package/src/sync/sync-backend-kv.ts +4 -3
  476. package/src/sync/sync-backend.ts +66 -17
  477. package/src/sync/sync.ts +24 -2
  478. package/src/sync/syncstate.test.ts +583 -419
  479. package/src/sync/syncstate.ts +127 -122
  480. package/src/sync/transport-chunking.ts +90 -0
  481. package/src/sync/validate-push-payload.ts +6 -8
  482. package/src/testing/event-factory.ts +10 -12
  483. package/src/util.ts +2 -2
  484. package/src/version.ts +33 -8
  485. package/dist/schema/EventDef.d.ts +0 -126
  486. package/dist/schema/EventDef.d.ts.map +0 -1
  487. package/dist/schema/EventDef.js +0 -46
  488. package/dist/schema/EventDef.js.map +0 -1
  489. package/dist/schema/EventSequenceNumber.d.ts +0 -80
  490. package/dist/schema/EventSequenceNumber.d.ts.map +0 -1
  491. package/dist/schema/EventSequenceNumber.js +0 -139
  492. package/dist/schema/EventSequenceNumber.js.map +0 -1
  493. package/dist/schema/LiveStoreEvent.d.ts.map +0 -1
  494. package/dist/schema/LiveStoreEvent.js +0 -147
  495. package/dist/schema/LiveStoreEvent.js.map +0 -1
  496. package/dist/schema/state/sqlite/system-tables.d.ts.map +0 -1
  497. package/dist/schema/state/sqlite/system-tables.js +0 -81
  498. package/dist/schema/state/sqlite/system-tables.js.map +0 -1
  499. package/dist/sync/next/graphology.d.ts +0 -8
  500. package/dist/sync/next/graphology.d.ts.map +0 -1
  501. package/dist/sync/next/graphology.js +0 -30
  502. package/dist/sync/next/graphology.js.map +0 -1
  503. package/dist/sync/next/graphology_.d.ts +0 -3
  504. package/dist/sync/next/graphology_.d.ts.map +0 -1
  505. package/dist/sync/next/graphology_.js +0 -3
  506. package/dist/sync/next/graphology_.js.map +0 -1
  507. package/src/schema/EventDef.ts +0 -222
  508. package/src/schema/EventSequenceNumber.ts +0 -199
  509. package/src/schema/LiveStoreEvent.ts +0 -286
  510. package/src/schema/state/sqlite/system-tables.ts +0 -106
  511. package/src/sync/next/ambient.d.ts +0 -3
  512. package/src/sync/next/graphology.ts +0 -41
  513. package/src/sync/next/graphology_.ts +0 -2
@@ -1,5 +1,7 @@
1
+ import { assert, describe, expect, it } from 'vitest'
2
+
1
3
  import { Schema } from '@livestore/utils/effect'
2
- import { describe, expect, it } from 'vitest'
4
+ import { objectToString } from '@livestore/utils'
3
5
 
4
6
  import * as State from '../mod.ts'
5
7
  import { withAutoIncrement, withColumnType, withDefault, withPrimaryKey, withUnique } from './column-annotations.ts'
@@ -144,11 +146,10 @@ describe('getColumnDefForSchema', () => {
144
146
 
145
147
  it('should map tagged unions to json column', () => {
146
148
  const ResultSchema = Schema.Union(
147
- Schema.Struct({
148
- _tag: Schema.Literal('success'),
149
+ Schema.TaggedStruct('success', {
149
150
  value: Schema.String,
150
151
  }),
151
- Schema.Struct({ _tag: Schema.Literal('error'), error: Schema.String }),
152
+ Schema.TaggedStruct('error', { error: Schema.String }),
152
153
  )
153
154
 
154
155
  const columnDef = State.SQLite.getColumnDefForSchema(ResultSchema)
@@ -273,17 +274,34 @@ describe('getColumnDefForSchema', () => {
273
274
  INACTIVE: 'inactive',
274
275
  })
275
276
 
276
- const StatusUnion = Schema.Union(Schema.Literal('pending'), Schema.Literal('active'), Schema.Literal('inactive'))
277
+ const StatusUnion = Schema.Literal('pending', 'active', 'inactive')
277
278
 
278
279
  expect(State.SQLite.getColumnDefForSchema(StatusEnum).columnType).toBe('text')
279
280
  expect(State.SQLite.getColumnDefForSchema(StatusUnion).columnType).toBe('text')
280
281
  })
282
+
283
+ it('should handle unions of numeric literals as integer column', () => {
284
+ const IntervalSchema = Schema.Literal(1, 5, 15, 30)
285
+
286
+ const columnDef = State.SQLite.getColumnDefForSchema(IntervalSchema)
287
+
288
+ expect(columnDef.columnType).toBe('integer')
289
+ })
290
+
291
+ it('should handle unions of non-integer numeric literals as real column', () => {
292
+ const PercentSchema = Schema.Literal(0.1, 0.2, 0.25)
293
+
294
+ const columnDef = State.SQLite.getColumnDefForSchema(PercentSchema)
295
+
296
+ expect(columnDef.columnType).toBe('real')
297
+ })
281
298
  })
282
299
 
283
300
  describe('binary data', () => {
284
301
  it('should handle Uint8Array as blob column', () => {
285
302
  const columnDef = State.SQLite.getColumnDefForSchema(Schema.Uint8Array)
286
- expect(columnDef.columnType).toBe('text') // Stored as JSON
303
+ expect(columnDef.columnType).toBe('blob')
304
+ expect(objectToString(columnDef.schema)).toBe('Uint8ArrayFromSelf')
287
305
  })
288
306
  })
289
307
 
@@ -340,8 +358,8 @@ describe('getColumnDefForSchema', () => {
340
358
 
341
359
  expect(table.sqliteDef.columns.active.nullable).toBe(true)
342
360
  expect(table.sqliteDef.columns.active.columnType).toBe('integer')
343
- expect(table.sqliteDef.columns.active.schema.toString()).toBe('(number <-> boolean) | null')
344
- expect((table.rowSchema as any).fields.active.toString()).toBe('(number <-> boolean) | null')
361
+ expect(objectToString(table.sqliteDef.columns.active.schema)).toBe('(number <-> boolean) | null')
362
+ expect(String((table.rowSchema as any).fields.active)).toBe('(number <-> boolean) | null')
345
363
  })
346
364
 
347
365
  it('should handle optional complex types with JSON encoding', () => {
@@ -381,6 +399,19 @@ describe('getColumnDefForSchema', () => {
381
399
  expect((table.rowSchema as any).fields.count.toString()).toBe('Int | null')
382
400
  })
383
401
 
402
+ it('should treat unions of string literals as text columns without JSON parsing', () => {
403
+ const schema = Schema.Struct({
404
+ id: Schema.String,
405
+ status: Schema.Literal('idle', 'running', 'stopped'),
406
+ })
407
+
408
+ const table = State.SQLite.table({ name: 'timers', schema })
409
+
410
+ expect(table.sqliteDef.columns.status.columnType).toBe('text')
411
+ expect(objectToString(table.sqliteDef.columns.status.schema)).toBe('"idle" | "running" | "stopped"')
412
+ expect(String((table.rowSchema as any).fields.status)).toBe('"idle" | "running" | "stopped"')
413
+ })
414
+
384
415
  it('should handle Schema.NullOr with complex types', () => {
385
416
  const schema = Schema.Struct({
386
417
  data: Schema.NullOr(Schema.Struct({ value: Schema.Number })),
@@ -539,7 +570,7 @@ describe('getColumnDefForSchema', () => {
539
570
 
540
571
  it('should work with column type annotation', () => {
541
572
  const UserSchema = Schema.Struct({
542
- id: Schema.Number.pipe(withColumnType('integer')).pipe(withPrimaryKey),
573
+ id: Schema.Number.pipe(withColumnType('integer'), withPrimaryKey),
543
574
  name: Schema.String,
544
575
  })
545
576
 
@@ -571,7 +602,7 @@ describe('getColumnDefForSchema', () => {
571
602
  describe('withAutoIncrement', () => {
572
603
  it('should add autoIncrement annotation to schema', () => {
573
604
  const UserSchema = Schema.Struct({
574
- id: Schema.Int.pipe(withPrimaryKey).pipe(withAutoIncrement),
605
+ id: Schema.Int.pipe(withPrimaryKey, withAutoIncrement),
575
606
  name: Schema.String,
576
607
  })
577
608
  const userTable = State.SQLite.table({
@@ -623,6 +654,29 @@ describe('getColumnDefForSchema', () => {
623
654
  table2.sqliteDef.columns.count.default._tag === 'Some' && table2.sqliteDef.columns.count.default.value,
624
655
  ).toBe(0)
625
656
  })
657
+
658
+ it('should support thunk defaults without eager evaluation', () => {
659
+ let counter = 0
660
+ const UserSchema = Schema.Struct({
661
+ id: Schema.String.pipe(
662
+ withDefault(() => {
663
+ counter += 1
664
+ return `user-${counter}`
665
+ }),
666
+ ),
667
+ })
668
+
669
+ const table = State.SQLite.table({ name: 'users_with_thunk', schema: UserSchema })
670
+
671
+ expect(counter).toBe(0)
672
+ expect(table.sqliteDef.columns.id.default._tag).toBe('Some')
673
+ if (table.sqliteDef.columns.id.default._tag === 'Some') {
674
+ const defaultThunk = table.sqliteDef.columns.id.default.value
675
+ assert(typeof defaultThunk === 'function')
676
+ expect(defaultThunk()).toBe('user-1')
677
+ expect(defaultThunk()).toBe('user-2')
678
+ }
679
+ })
626
680
  })
627
681
 
628
682
  describe('withUnique', () => {
@@ -668,7 +722,7 @@ describe('getColumnDefForSchema', () => {
668
722
 
669
723
  describe('combined annotations', () => {
670
724
  it('should work with multiple annotations', () => {
671
- const schema = Schema.Uint8ArrayFromBase64.pipe(withColumnType('blob')).pipe(withPrimaryKey)
725
+ const schema = Schema.Uint8ArrayFromBase64.pipe(withColumnType('blob'), withPrimaryKey)
672
726
 
673
727
  const UserSchema = Schema.Struct({
674
728
  id: schema,
@@ -686,7 +740,7 @@ describe('getColumnDefForSchema', () => {
686
740
 
687
741
  it('should combine all annotations', () => {
688
742
  const UserSchema = Schema.Struct({
689
- id: Schema.Int.pipe(withPrimaryKey).pipe(withAutoIncrement),
743
+ id: Schema.Int.pipe(withPrimaryKey, withAutoIncrement),
690
744
  email: Schema.String.pipe(withUnique),
691
745
  status: Schema.String.pipe(withDefault('active')),
692
746
  metadata: Schema.Unknown.pipe(withColumnType('text')),
@@ -20,19 +20,20 @@ export const getColumnDefForSchema = (
20
20
 
21
21
  // Extract annotations
22
22
  const getAnnotation = <T>(annotationId: symbol): Option.Option<T> =>
23
- propertySignature
23
+ propertySignature !== undefined
24
24
  ? hasPropertyAnnotation<T>(propertySignature, annotationId)
25
25
  : SchemaAST.getAnnotation<T>(annotationId)(ast)
26
26
 
27
27
  const columnType = SchemaAST.getAnnotation<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
- const isNullable = forceNullable || hasNull(ast) || hasUndefined(ast)
30
+ const isNullable = forceNullable === true || hasNull(ast) === true || hasUndefined(ast) === true
31
31
 
32
32
  // Get base column definition with nullable flag
33
- const baseColumn = Option.isSome(columnType)
34
- ? getColumnForType(columnType.value, isNullable)
35
- : getColumnForSchema(schema, isNullable)
33
+ const baseColumn =
34
+ Option.isSome(columnType) === true
35
+ ? getColumnForType(columnType.value, isNullable)
36
+ : getColumnForSchema(schema, isNullable)
36
37
 
37
38
  // Apply annotations
38
39
  const primaryKey = getAnnotation<boolean>(PrimaryKeyId).pipe(Option.getOrElse(() => false))
@@ -41,9 +42,9 @@ export const getColumnDefForSchema = (
41
42
 
42
43
  return {
43
44
  ...baseColumn,
44
- ...(primaryKey && { primaryKey: true }),
45
- ...(autoIncrement && { autoIncrement: true }),
46
- ...(Option.isSome(defaultValue) && { default: Option.some(defaultValue.value) }),
45
+ ...(primaryKey === true ? { primaryKey: true } : {}),
46
+ ...(autoIncrement === true ? { autoIncrement: true } : {}),
47
+ ...(Option.isSome(defaultValue) === true ? { default: Option.some(defaultValue.value) } : {}),
47
48
  }
48
49
  }
49
50
 
@@ -51,9 +52,9 @@ const hasPropertyAnnotation = <T>(
51
52
  propertySignature: SchemaAST.PropertySignature,
52
53
  annotationId: symbol,
53
54
  ): Option.Option<T> => {
54
- if ('annotations' in propertySignature && propertySignature.annotations) {
55
+ if ('annotations' in propertySignature && propertySignature.annotations !== undefined) {
55
56
  const annotation = SchemaAST.getAnnotation<T>(annotationId)(propertySignature as any)
56
- if (Option.isSome(annotation)) return annotation
57
+ if (Option.isSome(annotation) === true) return annotation
57
58
  }
58
59
  return SchemaAST.getAnnotation<T>(annotationId)(propertySignature.type)
59
60
  }
@@ -74,15 +75,15 @@ export const schemaFieldsToColumns = (
74
75
  const fieldSchema = Schema.make(prop.type)
75
76
 
76
77
  // Warn about lossy conversion for fields with both null and undefined
77
- if (prop.isOptional) {
78
+ if (prop.isOptional === true) {
78
79
  const { hasNull, hasUndefined } = checkNullUndefined(fieldSchema.ast)
79
- if (hasNull && hasUndefined) {
80
+ if (hasNull === true && hasUndefined === true) {
80
81
  console.warn(`Field '${prop.name}' has both null and undefined - treating | undefined as | null`)
81
82
  }
82
83
  }
83
84
 
84
85
  // Get column definition - pass nullable flag for optional fields
85
- const columnDef = getColumnDefForSchema(fieldSchema, prop, prop.isOptional)
86
+ const columnDef = getColumnDefForSchema(fieldSchema, prop, prop.isOptional === true)
86
87
 
87
88
  // Check for primary key and unique annotations
88
89
  const hasPrimaryKey = hasPropertyAnnotation<boolean>(prop, PrimaryKeyId).pipe(Option.getOrElse(() => false))
@@ -91,16 +92,16 @@ export const schemaFieldsToColumns = (
91
92
  // Build final column
92
93
  columns[prop.name] = {
93
94
  ...columnDef,
94
- ...(hasPrimaryKey && { primaryKey: true }),
95
+ ...(hasPrimaryKey === true ? { primaryKey: true } : {}),
95
96
  }
96
97
 
97
98
  // Validate primary key + nullable
98
99
  const column = columns[prop.name]
99
- if (column?.primaryKey && column.nullable) {
100
+ if (column?.primaryKey === true && column.nullable === true) {
100
101
  throw new Error('Primary key columns cannot be nullable')
101
102
  }
102
103
 
103
- if (hasUnique) uniqueColumns.push(prop.name)
104
+ if (hasUnique === true) uniqueColumns.push(prop.name)
104
105
  }
105
106
 
106
107
  return { columns, uniqueColumns }
@@ -111,9 +112,9 @@ const checkNullUndefined = (ast: SchemaAST.AST): { hasNull: boolean; hasUndefine
111
112
  let hasUndefined = false
112
113
 
113
114
  const visit = (type: SchemaAST.AST): void => {
114
- if (SchemaAST.isUndefinedKeyword(type)) hasUndefined = true
115
- else if (SchemaAST.isLiteral(type) && type.literal === null) hasNull = true
116
- else if (SchemaAST.isUnion(type)) type.types.forEach(visit)
115
+ if (SchemaAST.isUndefinedKeyword(type) === true) hasUndefined = true
116
+ else if (SchemaAST.isLiteral(type) === true && type.literal === null) hasNull = true
117
+ else if (SchemaAST.isUnion(type) === true) type.types.forEach(visit)
117
118
  }
118
119
 
119
120
  visit(ast)
@@ -121,16 +122,16 @@ const checkNullUndefined = (ast: SchemaAST.AST): { hasNull: boolean; hasUndefine
121
122
  }
122
123
 
123
124
  const hasNull = (ast: SchemaAST.AST): boolean => {
124
- if (SchemaAST.isLiteral(ast) && ast.literal === null) return true
125
- if (SchemaAST.isUnion(ast)) {
125
+ if (SchemaAST.isLiteral(ast) === true && ast.literal === null) return true
126
+ if (SchemaAST.isUnion(ast) === true) {
126
127
  return ast.types.some((type) => hasNull(type))
127
128
  }
128
129
  return false
129
130
  }
130
131
 
131
132
  const hasUndefined = (ast: SchemaAST.AST): boolean => {
132
- if (SchemaAST.isUndefinedKeyword(ast)) return true
133
- if (SchemaAST.isUnion(ast)) {
133
+ if (SchemaAST.isUndefinedKeyword(ast) === true) return true
134
+ if (SchemaAST.isUnion(ast) === true) {
134
135
  return ast.types.some((type) => hasUndefined(type))
135
136
  }
136
137
  return false
@@ -158,7 +159,7 @@ const getColumnForSchema = (schema: Schema.Schema.AnyNoContext, nullable = false
158
159
  const coreSchema = stripNullable(ast) === ast ? schema : Schema.make(coreAst)
159
160
 
160
161
  // Special case: Boolean is transformed to integer in SQLite
161
- if (SchemaAST.isBooleanKeyword(coreAst)) {
162
+ if (SchemaAST.isBooleanKeyword(coreAst) === true) {
162
163
  return SqliteDsl.boolean({ nullable })
163
164
  }
164
165
 
@@ -166,11 +167,11 @@ const getColumnForSchema = (schema: Schema.Schema.AnyNoContext, nullable = false
166
167
  const encodedAst = Schema.encodedSchema(coreSchema).ast
167
168
 
168
169
  // Check if the encoded type matches SQLite native types
169
- if (SchemaAST.isStringKeyword(encodedAst)) {
170
+ if (SchemaAST.isStringKeyword(encodedAst) === true) {
170
171
  return SqliteDsl.text({ schema: coreSchema, nullable })
171
172
  }
172
173
 
173
- if (SchemaAST.isNumberKeyword(encodedAst)) {
174
+ if (SchemaAST.isNumberKeyword(encodedAst) === true) {
174
175
  // Special cases for integer columns
175
176
  const id = SchemaAST.getIdentifierAnnotation(coreAst).pipe(Option.getOrElse(() => ''))
176
177
  if (id === 'Int' || id === 'DateFromNumber') {
@@ -179,37 +180,108 @@ const getColumnForSchema = (schema: Schema.Schema.AnyNoContext, nullable = false
179
180
  return SqliteDsl.real({ schema: coreSchema, nullable })
180
181
  }
181
182
 
182
- // Literals based on their type
183
- if (SchemaAST.isLiteral(coreAst)) {
184
- const value = coreAst.literal
185
- if (typeof value === 'boolean') return SqliteDsl.boolean({ nullable })
183
+ if (isUint8ArraySchema(coreAst) === true || isUint8ArraySchema(encodedAst) === true) {
184
+ return SqliteDsl.blob({ schema: Schema.Uint8ArrayFromSelf as Schema.Schema<Uint8Array<ArrayBuffer>>, nullable })
186
185
  }
187
186
 
188
- // Literals based on their encoded type
189
- if (SchemaAST.isLiteral(encodedAst)) {
190
- const value = encodedAst.literal
191
- if (typeof value === 'string') return SqliteDsl.text({ schema: coreSchema, nullable })
192
- if (typeof value === 'number') {
193
- // Check if the original schema is Int
194
- const id = SchemaAST.getIdentifierAnnotation(coreAst).pipe(Option.getOrElse(() => ''))
195
- if (id === 'Int') {
196
- return SqliteDsl.integer({ schema: coreSchema, nullable })
197
- }
198
- return SqliteDsl.real({ schema: coreSchema, nullable })
199
- }
200
- }
187
+ const literalColumn = getLiteralColumnDefinition(encodedAst, coreSchema, nullable, coreAst)
188
+ if (literalColumn !== null) return literalColumn
189
+
190
+ // Fallback to checking the original AST in case the encoded schema differs
191
+ const coreLiteralColumn = getLiteralColumnDefinition(coreAst, coreSchema, nullable, coreAst)
192
+ if (coreLiteralColumn !== null) return coreLiteralColumn
201
193
 
202
194
  // Everything else needs JSON encoding
203
195
  return SqliteDsl.json({ schema: coreSchema, nullable })
204
196
  }
205
197
 
206
198
  const stripNullable = (ast: SchemaAST.AST): SchemaAST.AST => {
207
- if (!SchemaAST.isUnion(ast)) return ast
199
+ if (SchemaAST.isUnion(ast) === false) return ast
208
200
 
209
- // Find non-null/undefined type
210
- const core = ast.types.find(
201
+ // Filter out null/undefined members while preserving any annotations on the union
202
+ const coreTypes = ast.types.filter(
211
203
  (type) => !(SchemaAST.isLiteral(type) && type.literal === null) && !SchemaAST.isUndefinedKeyword(type),
212
204
  )
213
205
 
214
- return core || ast
206
+ if (coreTypes.length === 0 || coreTypes.length === ast.types.length) {
207
+ return ast
208
+ }
209
+
210
+ if (coreTypes.length === 1) {
211
+ return coreTypes[0]!
212
+ }
213
+
214
+ return SchemaAST.Union.make(coreTypes, ast.annotations)
215
+ }
216
+
217
+ const getLiteralColumnDefinition = (
218
+ ast: SchemaAST.AST,
219
+ schema: Schema.Schema.AnyNoContext,
220
+ nullable: boolean,
221
+ sourceAst: SchemaAST.AST,
222
+ ): SqliteDsl.ColumnDefinition.Any | null => {
223
+ const literalValues = extractLiteralValues(ast)
224
+ if (literalValues == null) return null
225
+
226
+ const literalType = getLiteralValueType(literalValues)
227
+ switch (literalType) {
228
+ case 'string':
229
+ return SqliteDsl.text({ schema, nullable })
230
+ case 'number': {
231
+ const id = SchemaAST.getIdentifierAnnotation(sourceAst).pipe(Option.getOrElse(() => ''))
232
+ if (id === 'Int' || id === 'DateFromNumber') {
233
+ return SqliteDsl.integer({ schema, nullable })
234
+ }
235
+
236
+ const useIntegerColumn =
237
+ literalValues.length > 1 && literalValues.every((value) => typeof value === 'number' && Number.isInteger(value))
238
+
239
+ return useIntegerColumn === true ? SqliteDsl.integer({ schema, nullable }) : SqliteDsl.real({ schema, nullable })
240
+ }
241
+ case 'boolean':
242
+ return SqliteDsl.boolean({ nullable })
243
+ case 'bigint':
244
+ return SqliteDsl.integer({ schema, nullable })
245
+ default:
246
+ return null
247
+ }
248
+ }
249
+
250
+ const extractLiteralValues = (ast: SchemaAST.AST): ReadonlyArray<SchemaAST.LiteralValue> | null => {
251
+ if (SchemaAST.isLiteral(ast) === true) return [ast.literal]
252
+
253
+ if (
254
+ SchemaAST.isUnion(ast) === true &&
255
+ ast.types.length > 0 &&
256
+ ast.types.every((type) => SchemaAST.isLiteral(type)) === true
257
+ ) {
258
+ return ast.types.map((type) => (type as SchemaAST.Literal).literal)
259
+ }
260
+
261
+ return null
262
+ }
263
+
264
+ const getLiteralValueType = (
265
+ literals: ReadonlyArray<SchemaAST.LiteralValue>,
266
+ ): 'string' | 'number' | 'boolean' | 'bigint' | null => {
267
+ const literalTypes = new Set(literals.map((value) => (value === null ? 'null' : typeof value)))
268
+ if (literalTypes.size !== 1) return null
269
+
270
+ const [literalType] = literalTypes
271
+ return literalType === 'string' || literalType === 'number' || literalType === 'boolean' || literalType === 'bigint'
272
+ ? literalType
273
+ : null
274
+ }
275
+
276
+ const isUint8ArraySchema = (ast: SchemaAST.AST): boolean => {
277
+ const identifier = SchemaAST.getIdentifierAnnotation(ast)
278
+ if (Option.isSome(identifier) === true && identifier.value.includes('Uint8Array') === true) {
279
+ return true
280
+ }
281
+
282
+ if (SchemaAST.isTupleType(ast) === true) {
283
+ return ast.elements.length === 0 && ast.rest.length === 1 && SchemaAST.isNumberKeyword(ast.rest[0]!.type)
284
+ }
285
+
286
+ return false
215
287
  }
@@ -1,5 +1,7 @@
1
- import { Option, Schema } from '@livestore/utils/effect'
2
1
  import { describe, expect, it } from 'vitest'
2
+
3
+ import { Option, Schema } from '@livestore/utils/effect'
4
+
3
5
  import { makeColumnSpec } from './column-spec.ts'
4
6
  import { SqliteAst } from './db-schema/mod.ts'
5
7
 
@@ -56,9 +58,9 @@ describe('makeColumnSpec', () => {
56
58
  )
57
59
 
58
60
  const result = makeColumnSpec(table)
59
- expect(result).toMatchInlineSnapshot(`"'order' integer not null , 'group' text "`)
60
- expect(result).toContain("'order'")
61
- expect(result).toContain("'group'")
61
+ expect(result).toMatchInlineSnapshot(`""order" integer not null , "group" text "`)
62
+ expect(result).toContain('"order"')
63
+ expect(result).toContain('"group"')
62
64
  })
63
65
 
64
66
  it('should handle basic columns with primary keys', () => {
@@ -69,8 +71,7 @@ describe('makeColumnSpec', () => {
69
71
  )
70
72
 
71
73
  const result = makeColumnSpec(table)
72
- expect(result).toMatchInlineSnapshot(`"'id' text not null , 'name' text , PRIMARY KEY ('id')"`)
73
- expect(result).toContain("PRIMARY KEY ('id')")
74
+ expect(result).toMatchInlineSnapshot(`""id" text primary key , "name" text "`)
74
75
  })
75
76
 
76
77
  it('should handle multi-column primary keys', () => {
@@ -85,9 +86,9 @@ describe('makeColumnSpec', () => {
85
86
 
86
87
  const result = makeColumnSpec(table)
87
88
  expect(result).toMatchInlineSnapshot(
88
- `"'tenant_id' text not null , 'user_id' text not null , PRIMARY KEY ('tenant_id', 'user_id')"`,
89
+ `""tenant_id" text not null , "user_id" text not null , PRIMARY KEY ("tenant_id", "user_id")"`,
89
90
  )
90
- expect(result).toContain("PRIMARY KEY ('tenant_id', 'user_id')")
91
+ expect(result).toContain('PRIMARY KEY ("tenant_id", "user_id")')
91
92
  })
92
93
 
93
94
  it('should handle auto-increment columns', () => {
@@ -101,9 +102,9 @@ describe('makeColumnSpec', () => {
101
102
  )
102
103
 
103
104
  const result = makeColumnSpec(table)
104
- expect(result).toMatchInlineSnapshot(`"'id' integer not null autoincrement , 'title' text , PRIMARY KEY ('id')"`)
105
+ expect(result).toMatchInlineSnapshot(`""id" integer primary key autoincrement , "title" text "`)
105
106
  expect(result).toContain('autoincrement')
106
- expect(result).toContain("PRIMARY KEY ('id')")
107
+ expect(result).not.toContain("PRIMARY KEY ('id')")
107
108
  })
108
109
 
109
110
  it('should handle columns with default values', () => {
@@ -121,7 +122,7 @@ describe('makeColumnSpec', () => {
121
122
 
122
123
  const result = makeColumnSpec(table)
123
124
  expect(result).toMatchInlineSnapshot(
124
- `"'id' integer not null , 'name' text not null , 'price' real default 0, 'active' integer default true, 'description' text default 'No description', PRIMARY KEY ('id')"`,
125
+ `""id" integer primary key , "name" text not null , "price" real default 0, "active" integer default true, "description" text default 'No description'"`,
125
126
  )
126
127
  expect(result).toContain('default 0')
127
128
  expect(result).toContain('default true')
@@ -141,12 +142,28 @@ describe('makeColumnSpec', () => {
141
142
 
142
143
  const result = makeColumnSpec(table)
143
144
  expect(result).toMatchInlineSnapshot(
144
- `"'id' integer not null , 'created_at' text default CURRENT_TIMESTAMP, 'random_value' real default RANDOM(), PRIMARY KEY ('id')"`,
145
+ `""id" integer primary key , "created_at" text default CURRENT_TIMESTAMP, "random_value" real default RANDOM()"`,
145
146
  )
146
147
  expect(result).toContain('default CURRENT_TIMESTAMP')
147
148
  expect(result).toContain('default RANDOM()')
148
149
  })
149
150
 
151
+ it('should omit default clause for thunk defaults', () => {
152
+ const table = SqliteAst.table(
153
+ 'thunks',
154
+ [
155
+ createColumn('id', 'integer', { nullable: false, primaryKey: true }),
156
+ createColumn('token', 'text', { defaultValue: () => 'dynamic-token' }),
157
+ ],
158
+ [],
159
+ )
160
+
161
+ const result = makeColumnSpec(table)
162
+ expect(result).toMatchInlineSnapshot(`""id" integer primary key , "token" text "`)
163
+ expect(result).not.toContain('dynamic-token')
164
+ expect(result).not.toMatch(/token" text\s+default/i)
165
+ })
166
+
150
167
  it('should handle null default values', () => {
151
168
  const table = SqliteAst.table(
152
169
  'nullable_defaults',
@@ -158,9 +175,7 @@ describe('makeColumnSpec', () => {
158
175
  )
159
176
 
160
177
  const result = makeColumnSpec(table)
161
- expect(result).toMatchInlineSnapshot(
162
- `"'id' integer not null , 'optional_text' text default null, PRIMARY KEY ('id')"`,
163
- )
178
+ expect(result).toMatchInlineSnapshot(`""id" integer primary key , "optional_text" text default null"`)
164
179
  expect(result).toContain('default null')
165
180
  })
166
181
 
@@ -190,7 +205,7 @@ describe('makeColumnSpec', () => {
190
205
 
191
206
  const result = makeColumnSpec(table)
192
207
  expect(result).toMatchInlineSnapshot(
193
- `"'id' integer not null autoincrement , 'name' text not null default 'Unnamed', 'created_at' text not null default CURRENT_TIMESTAMP, 'status' text default 'pending', PRIMARY KEY ('id')"`,
208
+ `""id" integer primary key autoincrement , "name" text not null default 'Unnamed', "created_at" text not null default CURRENT_TIMESTAMP, "status" text default 'pending'"`,
194
209
  )
195
210
  })
196
211
 
@@ -213,7 +228,7 @@ describe('makeColumnSpec', () => {
213
228
  const result = makeColumnSpec(table)
214
229
  // The makeColumnSpec function only generates column specifications, not indexes
215
230
  expect(result).toMatchInlineSnapshot(
216
- `"'id' integer not null autoincrement , 'email' text not null , 'username' text not null , 'created_at' text default CURRENT_TIMESTAMP, PRIMARY KEY ('id')"`,
231
+ `""id" integer primary key autoincrement , "email" text not null , "username" text not null , "created_at" text default CURRENT_TIMESTAMP"`,
217
232
  )
218
233
  // Verify the table has the indexes (even though they're not in the column spec)
219
234
  expect(table.indexes).toHaveLength(3)
@@ -1,4 +1,5 @@
1
1
  import { Schema } from '@livestore/utils/effect'
2
+
2
3
  import { type SqliteAst, SqliteDsl } from './db-schema/mod.ts'
3
4
 
4
5
  /**
@@ -10,33 +11,58 @@ import { type SqliteAst, SqliteDsl } from './db-schema/mod.ts'
10
11
  * ```
11
12
  */
12
13
  export const makeColumnSpec = (tableAst: SqliteAst.Table) => {
13
- const primaryKeys = tableAst.columns.filter((_) => _.primaryKey).map((_) => `'${_.name}'`)
14
- const columnDefStrs = tableAst.columns.map(toSqliteColumnSpec)
14
+ const pkColumns = tableAst.columns.filter((_) => _.primaryKey)
15
+ const hasSinglePk = pkColumns.length === 1
16
+ const pkColumn = hasSinglePk === true ? pkColumns[0] : undefined
17
+
18
+ // Build column definitions, handling the special SQLite rule that AUTOINCREMENT
19
+ // is only valid on a single column declared as INTEGER PRIMARY KEY (column-level).
20
+ const columnDefStrs = tableAst.columns.map((column) =>
21
+ toSqliteColumnSpec(column, {
22
+ inlinePrimaryKey: hasSinglePk && column === pkColumn && column.primaryKey,
23
+ }),
24
+ )
15
25
 
16
- if (primaryKeys.length > 0) {
17
- columnDefStrs.push(`PRIMARY KEY (${primaryKeys.join(', ')})`)
26
+ // For composite primary keys, add a table-level PRIMARY KEY clause.
27
+ if (pkColumns.length > 1) {
28
+ const quotedPkCols = pkColumns.map((_) => `"${_.name}"`)
29
+ columnDefStrs.push(`PRIMARY KEY (${quotedPkCols.join(', ')})`)
18
30
  }
19
31
 
20
32
  return columnDefStrs.join(', ')
21
33
  }
22
34
 
23
35
  /** NOTE primary keys are applied on a table level not on a column level to account for multi-column primary keys */
24
- const toSqliteColumnSpec = (column: SqliteAst.Column) => {
36
+ const toSqliteColumnSpec = (column: SqliteAst.Column, opts: { inlinePrimaryKey: boolean }) => {
25
37
  const columnTypeStr = column.type._tag
26
- const nullableStr = column.nullable === false ? 'not null' : ''
27
- const autoIncrementStr = column.autoIncrement ? 'autoincrement' : ''
38
+ // When PRIMARY KEY is declared inline, NOT NULL is implied and should not be emitted,
39
+ // and AUTOINCREMENT must immediately follow PRIMARY KEY within the same constraint.
40
+ const nullableStr = opts.inlinePrimaryKey === true ? '' : column.nullable === false ? 'not null' : ''
41
+
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
44
+
45
+ const pkStr = opts.inlinePrimaryKey === true ? 'primary key' : ''
46
+ const autoIncrementStr = includeAutoIncrement === true ? 'autoincrement' : ''
47
+
28
48
  const defaultValueStr = (() => {
29
49
  if (column.default._tag === 'None') return ''
30
50
 
31
- if (column.default.value === null) return 'default null'
32
- if (SqliteDsl.isSqlDefaultValue(column.default.value)) return `default ${column.default.value.sql}`
51
+ const defaultValue = column.default.value
52
+ if (SqliteDsl.isDefaultThunk(defaultValue) === true) return ''
53
+
54
+ const resolvedDefault = SqliteDsl.resolveColumnDefault(defaultValue)
55
+
56
+ if (resolvedDefault === null) return 'default null'
57
+ if (SqliteDsl.isSqlDefaultValue(resolvedDefault) === true) return `default ${resolvedDefault.sql}`
33
58
 
34
59
  const encodeValue = Schema.encodeSync(column.schema)
35
- const encodedDefaultValue = encodeValue(column.default.value)
60
+ const encodedDefaultValue = encodeValue(resolvedDefault)
36
61
 
37
62
  if (columnTypeStr === 'text') return `default '${encodedDefaultValue}'`
38
63
  return `default ${encodedDefaultValue}`
39
64
  })()
40
65
 
41
- return `'${column.name}' ${columnTypeStr} ${nullableStr} ${autoIncrementStr} ${defaultValueStr}`
66
+ // Ensure order: PRIMARY KEY [AUTOINCREMENT] [NOT NULL] ...
67
+ return `"${column.name}" ${columnTypeStr} ${pkStr} ${autoIncrementStr} ${nullableStr} ${defaultValueStr}`
42
68
  }
@@ -124,7 +124,7 @@ const trimInfoForHasing = (obj: Table | Column | Index | ForeignKey | DbSchema):
124
124
 
125
125
  // NEW: Include schema hash for JSON columns
126
126
  // This ensures that changes to the JSON schema are detected
127
- if (isJsonColumn(obj) && obj.schema) {
127
+ if (isJsonColumn(obj) === true && obj.schema !== undefined) {
128
128
  // Use Effect's Schema.hash for consistent hashing
129
129
  baseInfo.jsonSchemaHash = Schema.hash(obj.schema)
130
130
  }
@@ -155,7 +155,7 @@ const trimInfoForHasing = (obj: Table | Column | Index | ForeignKey | DbSchema):
155
155
  }
156
156
  }
157
157
  default: {
158
- throw new Error(`Unreachable: ${obj}`)
158
+ throw new Error(`Unreachable: ${String(obj)}`)
159
159
  }
160
160
  }
161
161
  }
@@ -1,6 +1,7 @@
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 * as F from './field-defs.ts'
5
6
 
6
7
  describe.concurrent('FieldDefs', () => {