@livestore/common 0.3.0-dev.8 → 0.3.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 (480) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/__tests__/fixture.d.ts +83 -221
  3. package/dist/__tests__/fixture.d.ts.map +1 -1
  4. package/dist/__tests__/fixture.js +33 -11
  5. package/dist/__tests__/fixture.js.map +1 -1
  6. package/dist/adapter-types.d.ts +120 -64
  7. package/dist/adapter-types.d.ts.map +1 -1
  8. package/dist/adapter-types.js +39 -8
  9. package/dist/adapter-types.js.map +1 -1
  10. package/dist/bounded-collections.d.ts.map +1 -1
  11. package/dist/debug-info.d.ts +1 -1
  12. package/dist/debug-info.d.ts.map +1 -1
  13. package/dist/debug-info.js +1 -0
  14. package/dist/debug-info.js.map +1 -1
  15. package/dist/devtools/devtools-messages-client-session.d.ts +390 -0
  16. package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -0
  17. package/dist/devtools/devtools-messages-client-session.js +97 -0
  18. package/dist/devtools/devtools-messages-client-session.js.map +1 -0
  19. package/dist/devtools/devtools-messages-common.d.ts +68 -0
  20. package/dist/devtools/devtools-messages-common.d.ts.map +1 -0
  21. package/dist/devtools/devtools-messages-common.js +60 -0
  22. package/dist/devtools/devtools-messages-common.js.map +1 -0
  23. package/dist/devtools/devtools-messages-leader.d.ts +394 -0
  24. package/dist/devtools/devtools-messages-leader.d.ts.map +1 -0
  25. package/dist/devtools/devtools-messages-leader.js +147 -0
  26. package/dist/devtools/devtools-messages-leader.js.map +1 -0
  27. package/dist/devtools/devtools-messages.d.ts +3 -580
  28. package/dist/devtools/devtools-messages.d.ts.map +1 -1
  29. package/dist/devtools/devtools-messages.js +3 -174
  30. package/dist/devtools/devtools-messages.js.map +1 -1
  31. package/dist/devtools/devtools-sessioninfo.d.ts +32 -0
  32. package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -0
  33. package/dist/devtools/devtools-sessioninfo.js +36 -0
  34. package/dist/devtools/devtools-sessioninfo.js.map +1 -0
  35. package/dist/devtools/mod.d.ts +55 -0
  36. package/dist/devtools/mod.d.ts.map +1 -0
  37. package/dist/devtools/mod.js +33 -0
  38. package/dist/devtools/mod.js.map +1 -0
  39. package/dist/index.d.ts +7 -9
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +7 -9
  42. package/dist/index.js.map +1 -1
  43. package/dist/leader-thread/LeaderSyncProcessor.d.ts +45 -30
  44. package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
  45. package/dist/leader-thread/LeaderSyncProcessor.js +484 -321
  46. package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
  47. package/dist/leader-thread/connection.d.ts +34 -6
  48. package/dist/leader-thread/connection.d.ts.map +1 -1
  49. package/dist/leader-thread/connection.js +22 -7
  50. package/dist/leader-thread/connection.js.map +1 -1
  51. package/dist/leader-thread/eventlog.d.ts +27 -0
  52. package/dist/leader-thread/eventlog.d.ts.map +1 -0
  53. package/dist/leader-thread/eventlog.js +119 -0
  54. package/dist/leader-thread/eventlog.js.map +1 -0
  55. package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
  56. package/dist/leader-thread/leader-worker-devtools.js +155 -80
  57. package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
  58. package/dist/leader-thread/make-leader-thread-layer.d.ts +22 -9
  59. package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
  60. package/dist/leader-thread/make-leader-thread-layer.js +67 -45
  61. package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
  62. package/dist/leader-thread/materialize-event.d.ts +16 -0
  63. package/dist/leader-thread/materialize-event.d.ts.map +1 -0
  64. package/dist/leader-thread/materialize-event.js +109 -0
  65. package/dist/leader-thread/materialize-event.js.map +1 -0
  66. package/dist/leader-thread/mod.d.ts +1 -1
  67. package/dist/leader-thread/mod.d.ts.map +1 -1
  68. package/dist/leader-thread/mod.js +1 -1
  69. package/dist/leader-thread/mod.js.map +1 -1
  70. package/dist/leader-thread/recreate-db.d.ts +4 -2
  71. package/dist/leader-thread/recreate-db.d.ts.map +1 -1
  72. package/dist/leader-thread/recreate-db.js +28 -32
  73. package/dist/leader-thread/recreate-db.js.map +1 -1
  74. package/dist/leader-thread/shutdown-channel.d.ts +2 -5
  75. package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
  76. package/dist/leader-thread/shutdown-channel.js +2 -4
  77. package/dist/leader-thread/shutdown-channel.js.map +1 -1
  78. package/dist/leader-thread/types.d.ts +85 -38
  79. package/dist/leader-thread/types.d.ts.map +1 -1
  80. package/dist/leader-thread/types.js +1 -3
  81. package/dist/leader-thread/types.js.map +1 -1
  82. package/dist/make-client-session.d.ts +23 -0
  83. package/dist/make-client-session.d.ts.map +1 -0
  84. package/dist/make-client-session.js +57 -0
  85. package/dist/make-client-session.js.map +1 -0
  86. package/dist/materializer-helper.d.ts +23 -0
  87. package/dist/materializer-helper.d.ts.map +1 -0
  88. package/dist/materializer-helper.js +86 -0
  89. package/dist/materializer-helper.js.map +1 -0
  90. package/dist/otel.d.ts +2 -0
  91. package/dist/otel.d.ts.map +1 -1
  92. package/dist/otel.js +5 -0
  93. package/dist/otel.js.map +1 -1
  94. package/dist/rematerialize-from-eventlog.d.ts +14 -0
  95. package/dist/rematerialize-from-eventlog.d.ts.map +1 -0
  96. package/dist/rematerialize-from-eventlog.js +64 -0
  97. package/dist/rematerialize-from-eventlog.js.map +1 -0
  98. package/dist/schema/EventDef.d.ts +146 -0
  99. package/dist/schema/EventDef.d.ts.map +1 -0
  100. package/dist/schema/EventDef.js +58 -0
  101. package/dist/schema/EventDef.js.map +1 -0
  102. package/dist/schema/EventSequenceNumber.d.ts +57 -0
  103. package/dist/schema/EventSequenceNumber.d.ts.map +1 -0
  104. package/dist/schema/EventSequenceNumber.js +82 -0
  105. package/dist/schema/EventSequenceNumber.js.map +1 -0
  106. package/dist/schema/EventSequenceNumber.test.d.ts +2 -0
  107. package/dist/schema/EventSequenceNumber.test.d.ts.map +1 -0
  108. package/dist/schema/EventSequenceNumber.test.js +11 -0
  109. package/dist/schema/EventSequenceNumber.test.js.map +1 -0
  110. package/dist/schema/LiveStoreEvent.d.ts +257 -0
  111. package/dist/schema/LiveStoreEvent.d.ts.map +1 -0
  112. package/dist/schema/LiveStoreEvent.js +117 -0
  113. package/dist/schema/LiveStoreEvent.js.map +1 -0
  114. package/dist/schema/events.d.ts +2 -0
  115. package/dist/schema/events.d.ts.map +1 -0
  116. package/dist/schema/events.js +2 -0
  117. package/dist/schema/events.js.map +1 -0
  118. package/dist/schema/mod.d.ts +8 -6
  119. package/dist/schema/mod.d.ts.map +1 -1
  120. package/dist/schema/mod.js +8 -6
  121. package/dist/schema/mod.js.map +1 -1
  122. package/dist/schema/schema.d.ts +50 -32
  123. package/dist/schema/schema.d.ts.map +1 -1
  124. package/dist/schema/schema.js +36 -43
  125. package/dist/schema/schema.js.map +1 -1
  126. package/dist/schema/state/mod.d.ts +3 -0
  127. package/dist/schema/state/mod.d.ts.map +1 -0
  128. package/dist/schema/state/mod.js +3 -0
  129. package/dist/schema/state/mod.js.map +1 -0
  130. package/dist/schema/state/sqlite/client-document-def.d.ts +223 -0
  131. package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -0
  132. package/dist/schema/state/sqlite/client-document-def.js +170 -0
  133. package/dist/schema/state/sqlite/client-document-def.js.map +1 -0
  134. package/dist/schema/state/sqlite/client-document-def.test.d.ts +2 -0
  135. package/dist/schema/state/sqlite/client-document-def.test.d.ts.map +1 -0
  136. package/dist/schema/state/sqlite/client-document-def.test.js +201 -0
  137. package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -0
  138. package/dist/schema/state/sqlite/db-schema/ast/sqlite.d.ts +69 -0
  139. package/dist/schema/state/sqlite/db-schema/ast/sqlite.d.ts.map +1 -0
  140. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js +71 -0
  141. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js.map +1 -0
  142. package/dist/schema/state/sqlite/db-schema/ast/validate.d.ts +3 -0
  143. package/dist/schema/state/sqlite/db-schema/ast/validate.d.ts.map +1 -0
  144. package/dist/schema/state/sqlite/db-schema/ast/validate.js +12 -0
  145. package/dist/schema/state/sqlite/db-schema/ast/validate.js.map +1 -0
  146. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts +90 -0
  147. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts.map +1 -0
  148. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js +87 -0
  149. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js.map +1 -0
  150. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.d.ts +2 -0
  151. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.d.ts.map +1 -0
  152. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js +29 -0
  153. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js.map +1 -0
  154. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts +90 -0
  155. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts.map +1 -0
  156. package/dist/schema/state/sqlite/db-schema/dsl/mod.js +41 -0
  157. package/dist/schema/state/sqlite/db-schema/dsl/mod.js.map +1 -0
  158. package/dist/schema/state/sqlite/db-schema/hash.d.ts +2 -0
  159. package/dist/schema/state/sqlite/db-schema/hash.d.ts.map +1 -0
  160. package/dist/schema/state/sqlite/db-schema/hash.js +14 -0
  161. package/dist/schema/state/sqlite/db-schema/hash.js.map +1 -0
  162. package/dist/schema/state/sqlite/db-schema/mod.d.ts +3 -0
  163. package/dist/schema/state/sqlite/db-schema/mod.d.ts.map +1 -0
  164. package/dist/schema/state/sqlite/db-schema/mod.js +3 -0
  165. package/dist/schema/state/sqlite/db-schema/mod.js.map +1 -0
  166. package/dist/schema/state/sqlite/mod.d.ts +17 -0
  167. package/dist/schema/state/sqlite/mod.d.ts.map +1 -0
  168. package/dist/schema/state/sqlite/mod.js +41 -0
  169. package/dist/schema/state/sqlite/mod.js.map +1 -0
  170. package/dist/schema/state/sqlite/query-builder/api.d.ts +294 -0
  171. package/dist/schema/state/sqlite/query-builder/api.d.ts.map +1 -0
  172. package/dist/schema/state/sqlite/query-builder/api.js +6 -0
  173. package/dist/schema/state/sqlite/query-builder/api.js.map +1 -0
  174. package/dist/schema/state/sqlite/query-builder/astToSql.d.ts +7 -0
  175. package/dist/schema/state/sqlite/query-builder/astToSql.d.ts.map +1 -0
  176. package/dist/schema/state/sqlite/query-builder/astToSql.js +190 -0
  177. package/dist/schema/state/sqlite/query-builder/astToSql.js.map +1 -0
  178. package/dist/schema/state/sqlite/query-builder/impl.d.ts +7 -0
  179. package/dist/schema/state/sqlite/query-builder/impl.d.ts.map +1 -0
  180. package/dist/schema/state/sqlite/query-builder/impl.js +286 -0
  181. package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -0
  182. package/dist/schema/state/sqlite/query-builder/impl.test.d.ts +87 -0
  183. package/dist/schema/state/sqlite/query-builder/impl.test.d.ts.map +1 -0
  184. package/dist/schema/state/sqlite/query-builder/impl.test.js +563 -0
  185. package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -0
  186. package/dist/{query-builder → schema/state/sqlite/query-builder}/mod.d.ts +7 -0
  187. package/dist/schema/state/sqlite/query-builder/mod.d.ts.map +1 -0
  188. package/dist/{query-builder → schema/state/sqlite/query-builder}/mod.js +7 -0
  189. package/dist/schema/state/sqlite/query-builder/mod.js.map +1 -0
  190. package/dist/schema/state/sqlite/schema-helpers.d.ts.map +1 -0
  191. package/dist/schema/{schema-helpers.js → state/sqlite/schema-helpers.js} +1 -1
  192. package/dist/schema/state/sqlite/schema-helpers.js.map +1 -0
  193. package/dist/schema/state/sqlite/system-tables.d.ts +574 -0
  194. package/dist/schema/state/sqlite/system-tables.d.ts.map +1 -0
  195. package/dist/schema/state/sqlite/system-tables.js +88 -0
  196. package/dist/schema/state/sqlite/system-tables.js.map +1 -0
  197. package/dist/schema/state/sqlite/table-def.d.ts +84 -0
  198. package/dist/schema/state/sqlite/table-def.d.ts.map +1 -0
  199. package/dist/schema/state/sqlite/table-def.js +36 -0
  200. package/dist/schema/state/sqlite/table-def.js.map +1 -0
  201. package/dist/schema-management/common.d.ts +7 -7
  202. package/dist/schema-management/common.d.ts.map +1 -1
  203. package/dist/schema-management/common.js.map +1 -1
  204. package/dist/schema-management/migrations.d.ts +6 -6
  205. package/dist/schema-management/migrations.d.ts.map +1 -1
  206. package/dist/schema-management/migrations.js +27 -18
  207. package/dist/schema-management/migrations.js.map +1 -1
  208. package/dist/schema-management/validate-schema.d.ts +8 -0
  209. package/dist/schema-management/validate-schema.d.ts.map +1 -0
  210. package/dist/schema-management/validate-schema.js +39 -0
  211. package/dist/schema-management/validate-schema.js.map +1 -0
  212. package/dist/sql-queries/misc.d.ts.map +1 -1
  213. package/dist/sql-queries/sql-queries.d.ts +1 -1
  214. package/dist/sql-queries/sql-queries.d.ts.map +1 -1
  215. package/dist/sql-queries/sql-queries.js.map +1 -1
  216. package/dist/sql-queries/sql-query-builder.d.ts +1 -1
  217. package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
  218. package/dist/sql-queries/sql-query-builder.js.map +1 -1
  219. package/dist/sql-queries/types.d.ts +2 -1
  220. package/dist/sql-queries/types.d.ts.map +1 -1
  221. package/dist/sql-queries/types.js.map +1 -1
  222. package/dist/sync/ClientSessionSyncProcessor.d.ts +40 -19
  223. package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
  224. package/dist/sync/ClientSessionSyncProcessor.js +150 -72
  225. package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
  226. package/dist/sync/next/compact-events.d.ts.map +1 -1
  227. package/dist/sync/next/compact-events.js +38 -35
  228. package/dist/sync/next/compact-events.js.map +1 -1
  229. package/dist/sync/next/facts.d.ts +21 -21
  230. package/dist/sync/next/facts.d.ts.map +1 -1
  231. package/dist/sync/next/facts.js +11 -11
  232. package/dist/sync/next/facts.js.map +1 -1
  233. package/dist/sync/next/history-dag-common.d.ts +9 -7
  234. package/dist/sync/next/history-dag-common.d.ts.map +1 -1
  235. package/dist/sync/next/history-dag-common.js +10 -5
  236. package/dist/sync/next/history-dag-common.js.map +1 -1
  237. package/dist/sync/next/history-dag.d.ts +0 -2
  238. package/dist/sync/next/history-dag.d.ts.map +1 -1
  239. package/dist/sync/next/history-dag.js +16 -14
  240. package/dist/sync/next/history-dag.js.map +1 -1
  241. package/dist/sync/next/rebase-events.d.ts +10 -8
  242. package/dist/sync/next/rebase-events.d.ts.map +1 -1
  243. package/dist/sync/next/rebase-events.js +18 -10
  244. package/dist/sync/next/rebase-events.js.map +1 -1
  245. package/dist/sync/next/test/compact-events.calculator.test.js +39 -34
  246. package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
  247. package/dist/sync/next/test/compact-events.test.js +77 -77
  248. package/dist/sync/next/test/compact-events.test.js.map +1 -1
  249. package/dist/sync/next/test/{mutation-fixtures.d.ts → event-fixtures.d.ts} +35 -25
  250. package/dist/sync/next/test/event-fixtures.d.ts.map +1 -0
  251. package/dist/sync/next/test/{mutation-fixtures.js → event-fixtures.js} +81 -38
  252. package/dist/sync/next/test/event-fixtures.js.map +1 -0
  253. package/dist/sync/next/test/mod.d.ts +1 -1
  254. package/dist/sync/next/test/mod.d.ts.map +1 -1
  255. package/dist/sync/next/test/mod.js +1 -1
  256. package/dist/sync/next/test/mod.js.map +1 -1
  257. package/dist/sync/sync.d.ts +46 -21
  258. package/dist/sync/sync.d.ts.map +1 -1
  259. package/dist/sync/sync.js +10 -6
  260. package/dist/sync/sync.js.map +1 -1
  261. package/dist/sync/syncstate.d.ts +213 -82
  262. package/dist/sync/syncstate.d.ts.map +1 -1
  263. package/dist/sync/syncstate.js +337 -139
  264. package/dist/sync/syncstate.js.map +1 -1
  265. package/dist/sync/syncstate.test.js +309 -286
  266. package/dist/sync/syncstate.test.js.map +1 -1
  267. package/dist/sync/validate-push-payload.d.ts +2 -2
  268. package/dist/sync/validate-push-payload.d.ts.map +1 -1
  269. package/dist/sync/validate-push-payload.js +4 -4
  270. package/dist/sync/validate-push-payload.js.map +1 -1
  271. package/dist/util.d.ts +2 -2
  272. package/dist/util.d.ts.map +1 -1
  273. package/dist/version.d.ts +2 -2
  274. package/dist/version.d.ts.map +1 -1
  275. package/dist/version.js +2 -2
  276. package/dist/version.js.map +1 -1
  277. package/package.json +10 -4
  278. package/src/__tests__/fixture.ts +36 -15
  279. package/src/adapter-types.ts +107 -68
  280. package/src/debug-info.ts +1 -0
  281. package/src/devtools/devtools-messages-client-session.ts +142 -0
  282. package/src/devtools/devtools-messages-common.ts +115 -0
  283. package/src/devtools/devtools-messages-leader.ts +191 -0
  284. package/src/devtools/devtools-messages.ts +3 -246
  285. package/src/devtools/devtools-sessioninfo.ts +101 -0
  286. package/src/devtools/mod.ts +59 -0
  287. package/src/index.ts +7 -9
  288. package/src/leader-thread/LeaderSyncProcessor.ts +738 -477
  289. package/src/leader-thread/connection.ts +54 -9
  290. package/src/leader-thread/eventlog.ts +199 -0
  291. package/src/leader-thread/leader-worker-devtools.ts +227 -104
  292. package/src/leader-thread/make-leader-thread-layer.ts +121 -72
  293. package/src/leader-thread/materialize-event.ts +173 -0
  294. package/src/leader-thread/mod.ts +1 -1
  295. package/src/leader-thread/recreate-db.ts +33 -38
  296. package/src/leader-thread/shutdown-channel.ts +2 -4
  297. package/src/leader-thread/types.ts +94 -48
  298. package/src/make-client-session.ts +136 -0
  299. package/src/materializer-helper.ts +138 -0
  300. package/src/otel.ts +8 -0
  301. package/src/rematerialize-from-eventlog.ts +117 -0
  302. package/src/schema/EventDef.ts +227 -0
  303. package/src/schema/EventSequenceNumber.test.ts +12 -0
  304. package/src/schema/EventSequenceNumber.ts +121 -0
  305. package/src/schema/LiveStoreEvent.ts +240 -0
  306. package/src/schema/events.ts +1 -0
  307. package/src/schema/mod.ts +8 -6
  308. package/src/schema/schema.ts +88 -84
  309. package/src/schema/state/mod.ts +2 -0
  310. package/src/schema/state/sqlite/client-document-def.test.ts +238 -0
  311. package/src/schema/state/sqlite/client-document-def.ts +444 -0
  312. package/src/schema/state/sqlite/db-schema/ast/sqlite.ts +142 -0
  313. package/src/schema/state/sqlite/db-schema/ast/validate.ts +13 -0
  314. package/src/schema/state/sqlite/db-schema/dsl/__snapshots__/field-defs.test.ts.snap +206 -0
  315. package/src/schema/state/sqlite/db-schema/dsl/field-defs.test.ts +35 -0
  316. package/src/schema/state/sqlite/db-schema/dsl/field-defs.ts +242 -0
  317. package/src/schema/state/sqlite/db-schema/dsl/mod.ts +222 -0
  318. package/src/schema/state/sqlite/db-schema/hash.ts +14 -0
  319. package/src/schema/state/sqlite/db-schema/mod.ts +2 -0
  320. package/src/schema/state/sqlite/mod.ts +73 -0
  321. package/src/schema/state/sqlite/query-builder/api.ts +440 -0
  322. package/src/schema/state/sqlite/query-builder/astToSql.ts +232 -0
  323. package/src/schema/state/sqlite/query-builder/impl.test.ts +617 -0
  324. package/src/schema/state/sqlite/query-builder/impl.ts +351 -0
  325. package/src/{query-builder → schema/state/sqlite/query-builder}/mod.ts +7 -0
  326. package/src/schema/{schema-helpers.ts → state/sqlite/schema-helpers.ts} +1 -1
  327. package/src/schema/state/sqlite/system-tables.ts +117 -0
  328. package/src/schema/state/sqlite/table-def.ts +197 -0
  329. package/src/schema-management/common.ts +7 -7
  330. package/src/schema-management/migrations.ts +37 -31
  331. package/src/schema-management/validate-schema.ts +61 -0
  332. package/src/sql-queries/sql-queries.ts +1 -1
  333. package/src/sql-queries/sql-query-builder.ts +1 -2
  334. package/src/sql-queries/types.ts +3 -1
  335. package/src/sync/ClientSessionSyncProcessor.ts +220 -94
  336. package/src/sync/next/compact-events.ts +38 -35
  337. package/src/sync/next/facts.ts +43 -41
  338. package/src/sync/next/history-dag-common.ts +17 -10
  339. package/src/sync/next/history-dag.ts +16 -17
  340. package/src/sync/next/rebase-events.ts +29 -17
  341. package/src/sync/next/test/compact-events.calculator.test.ts +46 -46
  342. package/src/sync/next/test/compact-events.test.ts +79 -79
  343. package/src/sync/next/test/event-fixtures.ts +226 -0
  344. package/src/sync/next/test/mod.ts +1 -1
  345. package/src/sync/sync.ts +46 -21
  346. package/src/sync/syncstate.test.ts +346 -320
  347. package/src/sync/syncstate.ts +422 -230
  348. package/src/sync/validate-push-payload.ts +6 -6
  349. package/src/version.ts +2 -2
  350. package/dist/derived-mutations.d.ts +0 -109
  351. package/dist/derived-mutations.d.ts.map +0 -1
  352. package/dist/derived-mutations.js +0 -54
  353. package/dist/derived-mutations.js.map +0 -1
  354. package/dist/derived-mutations.test.d.ts +0 -2
  355. package/dist/derived-mutations.test.d.ts.map +0 -1
  356. package/dist/derived-mutations.test.js +0 -93
  357. package/dist/derived-mutations.test.js.map +0 -1
  358. package/dist/devtools/devtools-bridge.d.ts +0 -13
  359. package/dist/devtools/devtools-bridge.d.ts.map +0 -1
  360. package/dist/devtools/devtools-bridge.js +0 -2
  361. package/dist/devtools/devtools-bridge.js.map +0 -1
  362. package/dist/devtools/devtools-window-message.d.ts +0 -29
  363. package/dist/devtools/devtools-window-message.d.ts.map +0 -1
  364. package/dist/devtools/devtools-window-message.js +0 -33
  365. package/dist/devtools/devtools-window-message.js.map +0 -1
  366. package/dist/devtools/index.d.ts +0 -42
  367. package/dist/devtools/index.d.ts.map +0 -1
  368. package/dist/devtools/index.js +0 -48
  369. package/dist/devtools/index.js.map +0 -1
  370. package/dist/init-singleton-tables.d.ts +0 -4
  371. package/dist/init-singleton-tables.d.ts.map +0 -1
  372. package/dist/init-singleton-tables.js +0 -16
  373. package/dist/init-singleton-tables.js.map +0 -1
  374. package/dist/leader-thread/apply-mutation.d.ts +0 -11
  375. package/dist/leader-thread/apply-mutation.d.ts.map +0 -1
  376. package/dist/leader-thread/apply-mutation.js +0 -107
  377. package/dist/leader-thread/apply-mutation.js.map +0 -1
  378. package/dist/leader-thread/leader-sync-processor.d.ts +0 -47
  379. package/dist/leader-thread/leader-sync-processor.d.ts.map +0 -1
  380. package/dist/leader-thread/leader-sync-processor.js +0 -430
  381. package/dist/leader-thread/leader-sync-processor.js.map +0 -1
  382. package/dist/leader-thread/mutationlog.d.ts +0 -10
  383. package/dist/leader-thread/mutationlog.d.ts.map +0 -1
  384. package/dist/leader-thread/mutationlog.js +0 -28
  385. package/dist/leader-thread/mutationlog.js.map +0 -1
  386. package/dist/leader-thread/pull-queue-set.d.ts +0 -7
  387. package/dist/leader-thread/pull-queue-set.d.ts.map +0 -1
  388. package/dist/leader-thread/pull-queue-set.js +0 -39
  389. package/dist/leader-thread/pull-queue-set.js.map +0 -1
  390. package/dist/mutation.d.ts +0 -20
  391. package/dist/mutation.d.ts.map +0 -1
  392. package/dist/mutation.js +0 -57
  393. package/dist/mutation.js.map +0 -1
  394. package/dist/query-builder/api.d.ts +0 -190
  395. package/dist/query-builder/api.d.ts.map +0 -1
  396. package/dist/query-builder/api.js +0 -8
  397. package/dist/query-builder/api.js.map +0 -1
  398. package/dist/query-builder/impl.d.ts +0 -12
  399. package/dist/query-builder/impl.d.ts.map +0 -1
  400. package/dist/query-builder/impl.js +0 -244
  401. package/dist/query-builder/impl.js.map +0 -1
  402. package/dist/query-builder/impl.test.d.ts +0 -2
  403. package/dist/query-builder/impl.test.d.ts.map +0 -1
  404. package/dist/query-builder/impl.test.js +0 -212
  405. package/dist/query-builder/impl.test.js.map +0 -1
  406. package/dist/query-builder/mod.d.ts.map +0 -1
  407. package/dist/query-builder/mod.js.map +0 -1
  408. package/dist/query-info.d.ts +0 -38
  409. package/dist/query-info.d.ts.map +0 -1
  410. package/dist/query-info.js +0 -7
  411. package/dist/query-info.js.map +0 -1
  412. package/dist/rehydrate-from-mutationlog.d.ts +0 -14
  413. package/dist/rehydrate-from-mutationlog.d.ts.map +0 -1
  414. package/dist/rehydrate-from-mutationlog.js +0 -66
  415. package/dist/rehydrate-from-mutationlog.js.map +0 -1
  416. package/dist/schema/EventId.d.ts +0 -39
  417. package/dist/schema/EventId.d.ts.map +0 -1
  418. package/dist/schema/EventId.js +0 -38
  419. package/dist/schema/EventId.js.map +0 -1
  420. package/dist/schema/EventId.test.d.ts +0 -2
  421. package/dist/schema/EventId.test.d.ts.map +0 -1
  422. package/dist/schema/EventId.test.js +0 -11
  423. package/dist/schema/EventId.test.js.map +0 -1
  424. package/dist/schema/MutationEvent.d.ts +0 -166
  425. package/dist/schema/MutationEvent.d.ts.map +0 -1
  426. package/dist/schema/MutationEvent.js +0 -72
  427. package/dist/schema/MutationEvent.js.map +0 -1
  428. package/dist/schema/MutationEvent.test.d.ts +0 -2
  429. package/dist/schema/MutationEvent.test.d.ts.map +0 -1
  430. package/dist/schema/MutationEvent.test.js +0 -2
  431. package/dist/schema/MutationEvent.test.js.map +0 -1
  432. package/dist/schema/mutations.d.ts +0 -107
  433. package/dist/schema/mutations.d.ts.map +0 -1
  434. package/dist/schema/mutations.js +0 -42
  435. package/dist/schema/mutations.js.map +0 -1
  436. package/dist/schema/schema-helpers.d.ts.map +0 -1
  437. package/dist/schema/schema-helpers.js.map +0 -1
  438. package/dist/schema/system-tables.d.ts +0 -399
  439. package/dist/schema/system-tables.d.ts.map +0 -1
  440. package/dist/schema/system-tables.js +0 -59
  441. package/dist/schema/system-tables.js.map +0 -1
  442. package/dist/schema/table-def.d.ts +0 -156
  443. package/dist/schema/table-def.d.ts.map +0 -1
  444. package/dist/schema/table-def.js +0 -79
  445. package/dist/schema/table-def.js.map +0 -1
  446. package/dist/schema-management/validate-mutation-defs.d.ts +0 -8
  447. package/dist/schema-management/validate-mutation-defs.d.ts.map +0 -1
  448. package/dist/schema-management/validate-mutation-defs.js +0 -39
  449. package/dist/schema-management/validate-mutation-defs.js.map +0 -1
  450. package/dist/sync/client-session-sync-processor.d.ts +0 -45
  451. package/dist/sync/client-session-sync-processor.d.ts.map +0 -1
  452. package/dist/sync/client-session-sync-processor.js +0 -131
  453. package/dist/sync/client-session-sync-processor.js.map +0 -1
  454. package/dist/sync/next/test/mutation-fixtures.d.ts.map +0 -1
  455. package/dist/sync/next/test/mutation-fixtures.js.map +0 -1
  456. package/src/derived-mutations.test.ts +0 -101
  457. package/src/derived-mutations.ts +0 -170
  458. package/src/devtools/devtools-bridge.ts +0 -14
  459. package/src/devtools/devtools-window-message.ts +0 -27
  460. package/src/devtools/index.ts +0 -48
  461. package/src/init-singleton-tables.ts +0 -24
  462. package/src/leader-thread/apply-mutation.ts +0 -161
  463. package/src/leader-thread/mutationlog.ts +0 -46
  464. package/src/leader-thread/pull-queue-set.ts +0 -58
  465. package/src/mutation.ts +0 -91
  466. package/src/query-builder/api.ts +0 -289
  467. package/src/query-builder/impl.test.ts +0 -239
  468. package/src/query-builder/impl.ts +0 -285
  469. package/src/query-info.ts +0 -78
  470. package/src/rehydrate-from-mutationlog.ts +0 -119
  471. package/src/schema/EventId.test.ts +0 -12
  472. package/src/schema/EventId.ts +0 -60
  473. package/src/schema/MutationEvent.ts +0 -181
  474. package/src/schema/mutations.ts +0 -192
  475. package/src/schema/system-tables.ts +0 -105
  476. package/src/schema/table-def.ts +0 -343
  477. package/src/schema-management/validate-mutation-defs.ts +0 -63
  478. package/src/sync/next/test/mutation-fixtures.ts +0 -224
  479. package/tsconfig.json +0 -11
  480. /package/dist/schema/{schema-helpers.d.ts → state/sqlite/schema-helpers.d.ts} +0 -0
@@ -0,0 +1,206 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`FieldDefs > boolean 1`] = `
4
+ {
5
+ "columnType": "text",
6
+ "default": {
7
+ "_id": "Option",
8
+ "_tag": "None",
9
+ },
10
+ "nullable": false,
11
+ "primaryKey": false,
12
+ "schema": [Function],
13
+ }
14
+ `;
15
+
16
+ exports[`FieldDefs > boolean 2`] = `
17
+ {
18
+ "columnType": "text",
19
+ "default": {
20
+ "_id": "Option",
21
+ "_tag": "None",
22
+ },
23
+ "nullable": false,
24
+ "primaryKey": false,
25
+ "schema": [Function],
26
+ }
27
+ `;
28
+
29
+ exports[`FieldDefs > boolean 3`] = `
30
+ {
31
+ "columnType": "text",
32
+ "default": {
33
+ "_id": "Option",
34
+ "_tag": "Some",
35
+ "value": null,
36
+ },
37
+ "nullable": true,
38
+ "primaryKey": false,
39
+ "schema": [Function],
40
+ }
41
+ `;
42
+
43
+ exports[`FieldDefs > boolean 4`] = `
44
+ {
45
+ "columnType": "text",
46
+ "default": {
47
+ "_id": "Option",
48
+ "_tag": "Some",
49
+ "value": "foo",
50
+ },
51
+ "nullable": true,
52
+ "primaryKey": false,
53
+ "schema": [Function],
54
+ }
55
+ `;
56
+
57
+ exports[`FieldDefs > boolean 5`] = `
58
+ {
59
+ "columnType": "text",
60
+ "default": {
61
+ "_id": "Option",
62
+ "_tag": "Some",
63
+ "value": "foo",
64
+ },
65
+ "nullable": true,
66
+ "primaryKey": false,
67
+ "schema": [Function],
68
+ }
69
+ `;
70
+
71
+ exports[`FieldDefs > boolean 6`] = `
72
+ {
73
+ "columnType": "text",
74
+ "default": {
75
+ "_id": "Option",
76
+ "_tag": "None",
77
+ },
78
+ "nullable": false,
79
+ "primaryKey": false,
80
+ "schema": [Function],
81
+ }
82
+ `;
83
+
84
+ exports[`FieldDefs > boolean 7`] = `
85
+ {
86
+ "columnType": "text",
87
+ "default": {
88
+ "_id": "Option",
89
+ "_tag": "Some",
90
+ "value": null,
91
+ },
92
+ "nullable": true,
93
+ "primaryKey": false,
94
+ "schema": [Function],
95
+ }
96
+ `;
97
+
98
+ exports[`FieldDefs > boolean 8`] = `
99
+ {
100
+ "columnType": "text",
101
+ "default": {
102
+ "_id": "Option",
103
+ "_tag": "Some",
104
+ "value": {
105
+ "name": "Bob",
106
+ },
107
+ },
108
+ "nullable": true,
109
+ "primaryKey": false,
110
+ "schema": [Function],
111
+ }
112
+ `;
113
+
114
+ exports[`FieldDefs > boolean 9`] = `
115
+ {
116
+ "columnType": "text",
117
+ "default": {
118
+ "_id": "Option",
119
+ "_tag": "None",
120
+ },
121
+ "nullable": false,
122
+ "primaryKey": false,
123
+ "schema": [Function],
124
+ }
125
+ `;
126
+
127
+ exports[`FieldDefs > boolean 10`] = `
128
+ {
129
+ "columnType": "text",
130
+ "default": {
131
+ "_id": "Option",
132
+ "_tag": "None",
133
+ },
134
+ "nullable": false,
135
+ "primaryKey": false,
136
+ "schema": [Function],
137
+ }
138
+ `;
139
+
140
+ exports[`FieldDefs > boolean 11`] = `
141
+ {
142
+ "columnType": "text",
143
+ "default": {
144
+ "_id": "Option",
145
+ "_tag": "Some",
146
+ "value": null,
147
+ },
148
+ "nullable": true,
149
+ "primaryKey": false,
150
+ "schema": [Function],
151
+ }
152
+ `;
153
+
154
+ exports[`FieldDefs > boolean 12`] = `
155
+ {
156
+ "columnType": "text",
157
+ "default": {
158
+ "_id": "Option",
159
+ "_tag": "Some",
160
+ "value": 2022-02-02T00:00:00.000Z,
161
+ },
162
+ "nullable": false,
163
+ "primaryKey": false,
164
+ "schema": [Function],
165
+ }
166
+ `;
167
+
168
+ exports[`FieldDefs > boolean 13`] = `
169
+ {
170
+ "columnType": "integer",
171
+ "default": {
172
+ "_id": "Option",
173
+ "_tag": "None",
174
+ },
175
+ "nullable": false,
176
+ "primaryKey": false,
177
+ "schema": [Function],
178
+ }
179
+ `;
180
+
181
+ exports[`FieldDefs > boolean 14`] = `
182
+ {
183
+ "columnType": "integer",
184
+ "default": {
185
+ "_id": "Option",
186
+ "_tag": "None",
187
+ },
188
+ "nullable": false,
189
+ "primaryKey": false,
190
+ "schema": [Function],
191
+ }
192
+ `;
193
+
194
+ exports[`FieldDefs > boolean 15`] = `
195
+ {
196
+ "columnType": "integer",
197
+ "default": {
198
+ "_id": "Option",
199
+ "_tag": "Some",
200
+ "value": false,
201
+ },
202
+ "nullable": false,
203
+ "primaryKey": false,
204
+ "schema": [Function],
205
+ }
206
+ `;
@@ -0,0 +1,35 @@
1
+ import { Schema } from '@livestore/utils/effect'
2
+ import { describe, expect, test } from 'vitest'
3
+
4
+ import * as F from './field-defs.js'
5
+
6
+ describe.concurrent('FieldDefs', () => {
7
+ test('text', () => {
8
+ expect(F.text()).toMatchSnapshot()
9
+ expect(F.text({})).toMatchSnapshot()
10
+ expect(F.text({ default: null, nullable: true })).toMatchSnapshot()
11
+ expect(F.text({ schema: Schema.Literal('foo'), nullable: true, default: 'foo' })).toMatchSnapshot()
12
+ expect(F.text({ schema: Schema.Union(Schema.Literal('foo')), nullable: true, default: 'foo' })).toMatchSnapshot()
13
+ })
14
+
15
+ test('json', () => {
16
+ expect(F.json()).toMatchSnapshot()
17
+ expect(F.json({ default: null, nullable: true })).toMatchSnapshot()
18
+ expect(
19
+ F.json({ schema: Schema.Struct({ name: Schema.String }), default: { name: 'Bob' }, nullable: true }),
20
+ ).toMatchSnapshot()
21
+ })
22
+
23
+ test('datetime', () => {
24
+ expect(F.datetime()).toMatchSnapshot()
25
+ expect(F.datetime({})).toMatchSnapshot()
26
+ expect(F.datetime({ default: null, nullable: true })).toMatchSnapshot()
27
+ expect(F.datetime({ default: new Date('2022-02-02') })).toMatchSnapshot()
28
+ })
29
+
30
+ test('boolean', () => {
31
+ expect(F.boolean()).toMatchSnapshot()
32
+ expect(F.boolean({})).toMatchSnapshot()
33
+ expect(F.boolean({ default: false })).toMatchSnapshot()
34
+ })
35
+ })
@@ -0,0 +1,242 @@
1
+ import { casesHandled } from '@livestore/utils'
2
+ import { Option, Schema } from '@livestore/utils/effect'
3
+
4
+ export type ColumnDefinition<TEncoded, TDecoded> = {
5
+ readonly columnType: FieldColumnType
6
+ readonly schema: Schema.Schema<TDecoded, TEncoded>
7
+ readonly default: Option.Option<TEncoded>
8
+ /** @default false */
9
+ readonly nullable: boolean
10
+ /** @default false */
11
+ readonly primaryKey: boolean
12
+ }
13
+
14
+ export const isColumnDefinition = (value: unknown): value is ColumnDefinition<any, any> => {
15
+ const validColumnTypes = ['text', 'integer', 'real', 'blob'] as const
16
+ return (
17
+ typeof value === 'object' &&
18
+ value !== null &&
19
+ 'columnType' in value &&
20
+ validColumnTypes.includes(value['columnType'] as any)
21
+ )
22
+ }
23
+
24
+ export type ColumnDefinitionInput = {
25
+ readonly schema?: Schema.Schema<unknown>
26
+ readonly default?: unknown | NoDefault
27
+ readonly nullable?: boolean
28
+ readonly primaryKey?: boolean
29
+ }
30
+
31
+ export const NoDefault = Symbol.for('NoDefault')
32
+ export type NoDefault = typeof NoDefault
33
+
34
+ export type SqlDefaultValue = {
35
+ readonly sql: string
36
+ }
37
+
38
+ export const isSqlDefaultValue = (value: unknown): value is SqlDefaultValue => {
39
+ return typeof value === 'object' && value !== null && 'sql' in value && typeof value['sql'] === 'string'
40
+ }
41
+
42
+ export type ColDefFn<TColumnType extends FieldColumnType> = {
43
+ (): {
44
+ columnType: TColumnType
45
+ schema: Schema.Schema<DefaultEncodedForColumnType<TColumnType>>
46
+ default: Option.None<never>
47
+ nullable: false
48
+ primaryKey: false
49
+ }
50
+ <
51
+ TEncoded extends DefaultEncodedForColumnType<TColumnType>,
52
+ TDecoded = DefaultEncodedForColumnType<TColumnType>,
53
+ const TNullable extends boolean = false,
54
+ const TDefault extends TDecoded | SqlDefaultValue | NoDefault | (TNullable extends true ? null : never) = NoDefault,
55
+ const TPrimaryKey extends boolean = false,
56
+ >(args: {
57
+ schema?: Schema.Schema<TDecoded, TEncoded>
58
+ default?: TDefault
59
+ nullable?: TNullable
60
+ primaryKey?: TPrimaryKey
61
+ }): {
62
+ columnType: TColumnType
63
+ schema: TNullable extends true
64
+ ? Schema.Schema<NoInfer<TDecoded> | null, NoInfer<TEncoded> | null>
65
+ : Schema.Schema<NoInfer<TDecoded>, NoInfer<TEncoded>>
66
+ default: TDefault extends NoDefault ? Option.None<never> : Option.Some<NoInfer<TDefault>>
67
+ nullable: NoInfer<TNullable>
68
+ primaryKey: NoInfer<TPrimaryKey>
69
+ }
70
+ }
71
+
72
+ const makeColDef =
73
+ <TColumnType extends FieldColumnType>(columnType: TColumnType): ColDefFn<TColumnType> =>
74
+ (def?: ColumnDefinitionInput) => {
75
+ const nullable = def?.nullable ?? false
76
+ const schemaWithoutNull: Schema.Schema<any> = def?.schema ?? defaultSchemaForColumnType(columnType)
77
+ const schema = nullable === true ? Schema.NullOr(schemaWithoutNull) : schemaWithoutNull
78
+ const default_ = def?.default === undefined || def.default === NoDefault ? Option.none() : Option.some(def.default)
79
+
80
+ return {
81
+ columnType,
82
+ schema,
83
+ default: default_,
84
+ nullable,
85
+ primaryKey: def?.primaryKey ?? false,
86
+ } as any
87
+ }
88
+
89
+ export const column = <TColumnType extends FieldColumnType>(columnType: TColumnType): ColDefFn<TColumnType> =>
90
+ makeColDef(columnType)
91
+
92
+ /// Column definitions
93
+
94
+ export const text: ColDefFn<'text'> = makeColDef('text')
95
+ export const integer: ColDefFn<'integer'> = makeColDef('integer')
96
+ export const real: ColDefFn<'real'> = makeColDef('real')
97
+ export const blob: ColDefFn<'blob'> = makeColDef('blob')
98
+
99
+ /**
100
+ * `NoInfer` is needed for some generics to work properly in certain cases.
101
+ * See full explanation here: https://gist.github.com/schickling/a15e96819826530492b41a10d79d3c04?permalink_comment_id=4805120#gistcomment-4805120
102
+ *
103
+ * Big thanks to @andarist for their help with this!
104
+ */
105
+ type NoInfer<T> = [T][T extends any ? 0 : never]
106
+
107
+ export type SpecializedColDefFn<
108
+ TColumnType extends FieldColumnType,
109
+ TAllowsCustomSchema extends boolean,
110
+ TBaseDecoded,
111
+ > = {
112
+ (): {
113
+ columnType: TColumnType
114
+ schema: Schema.Schema<TBaseDecoded, DefaultEncodedForColumnType<TColumnType>>
115
+ default: Option.None<never>
116
+ nullable: false
117
+ primaryKey: false
118
+ }
119
+ <
120
+ TDecoded = TBaseDecoded,
121
+ const TNullable extends boolean = false,
122
+ const TDefault extends TDecoded | NoDefault | (TNullable extends true ? null : never) = NoDefault,
123
+ const TPrimaryKey extends boolean = false,
124
+ >(
125
+ args: TAllowsCustomSchema extends true
126
+ ? {
127
+ schema?: Schema.Schema<TDecoded, any>
128
+ default?: TDefault
129
+ nullable?: TNullable
130
+ primaryKey?: TPrimaryKey
131
+ }
132
+ : {
133
+ default?: TDefault
134
+ nullable?: TNullable
135
+ primaryKey?: TPrimaryKey
136
+ },
137
+ ): {
138
+ columnType: TColumnType
139
+ schema: TNullable extends true
140
+ ? Schema.Schema<NoInfer<TDecoded> | null, DefaultEncodedForColumnType<TColumnType> | null>
141
+ : Schema.Schema<NoInfer<TDecoded>, DefaultEncodedForColumnType<TColumnType>>
142
+ default: TDefault extends NoDefault ? Option.None<never> : Option.Some<TDefault>
143
+ nullable: NoInfer<TNullable>
144
+ primaryKey: NoInfer<TPrimaryKey>
145
+ }
146
+ }
147
+
148
+ type MakeSpecializedColDefFn = {
149
+ <TColumnType extends FieldColumnType, TBaseDecoded>(
150
+ columnType: TColumnType,
151
+ opts: {
152
+ _tag: 'baseSchema'
153
+ baseSchema: Schema.Schema<TBaseDecoded, DefaultEncodedForColumnType<TColumnType>>
154
+ },
155
+ ): SpecializedColDefFn<TColumnType, false, TBaseDecoded>
156
+ <TColumnType extends FieldColumnType, TBaseDecoded>(
157
+ columnType: TColumnType,
158
+ opts: {
159
+ _tag: 'baseSchemaFn'
160
+ baseSchemaFn: <TDecoded>(
161
+ customSchema: Schema.Schema<TDecoded, TBaseDecoded> | undefined,
162
+ ) => Schema.Schema<TBaseDecoded, DefaultEncodedForColumnType<TColumnType>>
163
+ },
164
+ ): SpecializedColDefFn<TColumnType, true, TBaseDecoded>
165
+ }
166
+
167
+ const makeSpecializedColDef: MakeSpecializedColDefFn = (columnType, opts) => (def?: ColumnDefinitionInput) => {
168
+ const nullable = def?.nullable ?? false
169
+ const schemaWithoutNull = opts._tag === 'baseSchemaFn' ? opts.baseSchemaFn(def?.schema as any) : opts.baseSchema
170
+ const schema = nullable === true ? Schema.NullOr(schemaWithoutNull) : schemaWithoutNull
171
+ const default_ = def?.default === undefined || def.default === NoDefault ? Option.none() : Option.some(def.default)
172
+
173
+ return {
174
+ columnType,
175
+ schema,
176
+ default: default_,
177
+ nullable,
178
+ primaryKey: def?.primaryKey ?? false,
179
+ } as any
180
+ }
181
+
182
+ export const json: SpecializedColDefFn<'text', true, unknown> = makeSpecializedColDef('text', {
183
+ _tag: 'baseSchemaFn',
184
+ baseSchemaFn: (customSchema) => Schema.parseJson(customSchema ?? Schema.Any),
185
+ })
186
+
187
+ export const datetime: SpecializedColDefFn<'text', false, Date> = makeSpecializedColDef('text', {
188
+ _tag: 'baseSchema',
189
+ baseSchema: Schema.Date,
190
+ })
191
+
192
+ export const datetimeInteger: SpecializedColDefFn<'integer', false, Date> = makeSpecializedColDef('integer', {
193
+ _tag: 'baseSchema',
194
+ baseSchema: Schema.transform(Schema.Number, Schema.DateFromSelf, {
195
+ decode: (ms) => new Date(ms),
196
+ encode: (date) => date.getTime(),
197
+ }),
198
+ })
199
+
200
+ export const boolean: SpecializedColDefFn<'integer', false, boolean> = makeSpecializedColDef('integer', {
201
+ _tag: 'baseSchema',
202
+ baseSchema: Schema.transform(Schema.Number, Schema.Boolean, {
203
+ decode: (_) => _ === 1,
204
+ encode: (_) => (_ ? 1 : 0),
205
+ }),
206
+ })
207
+
208
+ export type FieldColumnType = 'text' | 'integer' | 'real' | 'blob'
209
+
210
+ export type DefaultEncodedForColumnType<TColumnType extends FieldColumnType> = TColumnType extends 'text'
211
+ ? string
212
+ : TColumnType extends 'integer'
213
+ ? number
214
+ : TColumnType extends 'real'
215
+ ? number
216
+ : TColumnType extends 'blob'
217
+ ? Uint8Array
218
+ : never
219
+
220
+ export const defaultSchemaForColumnType = <TColumnType extends FieldColumnType>(
221
+ columnType: TColumnType,
222
+ ): Schema.Schema<DefaultEncodedForColumnType<TColumnType>> => {
223
+ type T = DefaultEncodedForColumnType<TColumnType>
224
+
225
+ switch (columnType) {
226
+ case 'text': {
227
+ return Schema.String as any as Schema.Schema<T>
228
+ }
229
+ case 'integer': {
230
+ return Schema.Number as any as Schema.Schema<T>
231
+ }
232
+ case 'real': {
233
+ return Schema.Number as any as Schema.Schema<T>
234
+ }
235
+ case 'blob': {
236
+ return Schema.Uint8ArrayFromSelf as any as Schema.Schema<T>
237
+ }
238
+ default: {
239
+ return casesHandled(columnType)
240
+ }
241
+ }
242
+ }
@@ -0,0 +1,222 @@
1
+ import type { Nullable } from '@livestore/utils'
2
+ import type { Option, Types } from '@livestore/utils/effect'
3
+ import { Schema } from '@livestore/utils/effect'
4
+
5
+ import type * as SqliteAst from '../ast/sqlite.js'
6
+ import type { ColumnDefinition } from './field-defs.js'
7
+
8
+ export * from './field-defs.js'
9
+
10
+ export type DbSchema = {
11
+ [key: string]: TableDefinition<string, Columns>
12
+ }
13
+
14
+ /** Note when using the object-notation, the object keys are ignored and not used as table names */
15
+ export type DbSchemaInput = Record<string, TableDefinition<any, any>> | ReadonlyArray<TableDefinition<any, any>>
16
+
17
+ /**
18
+ * In case of ...
19
+ * - array: we use the table name of each array item (= table definition) as the object key
20
+ * - object: we discard the keys of the input object and use the table name of each object value (= table definition) as the new object key
21
+ */
22
+ export type DbSchemaFromInputSchema<TSchemaInput extends DbSchemaInput> =
23
+ TSchemaInput extends ReadonlyArray<TableDefinition<any, any>>
24
+ ? { [K in TSchemaInput[number] as K['name']]: K }
25
+ : TSchemaInput extends Record<string, TableDefinition<any, any>>
26
+ ? { [K in keyof TSchemaInput as TSchemaInput[K]['name']]: TSchemaInput[K] }
27
+ : never
28
+
29
+ // TODO ensure via runtime check (possibly even via type-level check) that all index names are unique
30
+ export const makeDbSchema = <TDbSchemaInput extends DbSchemaInput>(
31
+ schema: TDbSchemaInput,
32
+ ): DbSchemaFromInputSchema<TDbSchemaInput> => {
33
+ return Array.isArray(schema) ? Object.fromEntries(schema.map((_) => [_.name, _])) : (schema as any)
34
+ }
35
+
36
+ export const table = <TTableName extends string, TColumns extends Columns, TIndexes extends Index[]>(
37
+ name: TTableName,
38
+ columns: TColumns,
39
+ indexes?: TIndexes,
40
+ ): TableDefinition<TTableName, TColumns> => {
41
+ const ast: SqliteAst.Table = {
42
+ _tag: 'table',
43
+ name,
44
+ columns: columsToAst(columns),
45
+ indexes: indexesToAst(indexes ?? []),
46
+ }
47
+
48
+ return { name, columns, indexes, ast }
49
+ }
50
+
51
+ export type AnyIfConstained<In, Out> = '__constrained' extends keyof In ? any : Out
52
+ export type EmptyObjIfConstained<In> = '__constrained' extends keyof In ? {} : In
53
+
54
+ export type StructSchemaForColumns<TCols extends ConstraintColumns> = Schema.Schema<
55
+ AnyIfConstained<TCols, FromColumns.RowDecoded<TCols>>,
56
+ AnyIfConstained<TCols, FromColumns.RowEncoded<TCols>>
57
+ >
58
+
59
+ export type InsertStructSchemaForColumns<TCols extends ConstraintColumns> = Schema.Schema<
60
+ AnyIfConstained<TCols, FromColumns.InsertRowDecoded<TCols>>,
61
+ AnyIfConstained<TCols, FromColumns.InsertRowEncoded<TCols>>
62
+ >
63
+
64
+ export const structSchemaForTable = <TTableDefinition extends TableDefinition<any, any>>(
65
+ tableDef: TTableDefinition,
66
+ ): StructSchemaForColumns<TTableDefinition['columns']> =>
67
+ Schema.Struct(Object.fromEntries(tableDef.ast.columns.map((column) => [column.name, column.schema]))).annotations({
68
+ title: tableDef.name,
69
+ }) as any
70
+
71
+ export const insertStructSchemaForTable = <TTableDefinition extends TableDefinition<any, any>>(
72
+ tableDef: TTableDefinition,
73
+ ): InsertStructSchemaForColumns<TTableDefinition['columns']> =>
74
+ Schema.Struct(
75
+ Object.fromEntries(
76
+ tableDef.ast.columns.map((column) => [
77
+ column.name,
78
+ column.nullable === true || column.default._tag === 'Some' ? Schema.optional(column.schema) : column.schema,
79
+ ]),
80
+ ),
81
+ ).annotations({
82
+ title: tableDef.name,
83
+ }) as any
84
+
85
+ const columsToAst = (columns: Columns): ReadonlyArray<SqliteAst.Column> => {
86
+ return Object.entries(columns).map(([name, column]) => {
87
+ return {
88
+ _tag: 'column',
89
+ name,
90
+ schema: column.schema,
91
+ default: column.default as any,
92
+ nullable: column.nullable ?? false,
93
+ primaryKey: column.primaryKey ?? false,
94
+ type: { _tag: column.columnType },
95
+ } satisfies SqliteAst.Column
96
+ })
97
+ }
98
+
99
+ const indexesToAst = (indexes: ReadonlyArray<Index>): ReadonlyArray<SqliteAst.Index> => {
100
+ return indexes.map(
101
+ (_) => ({ _tag: 'index', columns: _.columns, name: _.name, unique: _.isUnique ?? false }) satisfies SqliteAst.Index,
102
+ )
103
+ }
104
+
105
+ /// Other
106
+
107
+ export type TableDefinition<TName extends string, TColumns extends Columns> = {
108
+ name: TName
109
+ columns: TColumns
110
+ indexes?: ReadonlyArray<Index>
111
+ ast: SqliteAst.Table
112
+ }
113
+
114
+ export type Columns = Record<string, ColumnDefinition<any, any>>
115
+
116
+ export type IsSingleColumn<TColumns extends Columns | ColumnDefinition<any, any>> =
117
+ TColumns extends ColumnDefinition<any, any> ? true : false
118
+
119
+ /**
120
+ * NOTE this is only needed to avoid a TS limitation where `StructSchemaForColumns` in the default case
121
+ * results in `Record<string, any>` instead of `any`. (Thanks to Andarist for the workaround)
122
+ *
123
+ * Hopefully this can be removed in the future
124
+ */
125
+ export type ConstraintColumns = Record<string, ColumnDefinition<any, any>> & { __constrained?: never }
126
+
127
+ export type Index = {
128
+ name: string
129
+ columns: ReadonlyArray<string>
130
+ /** @default false */
131
+ isUnique?: boolean
132
+ }
133
+
134
+ export namespace FromTable {
135
+ // TODO this sometimes doesn't preserve the order of columns
136
+ export type RowDecoded<TTableDefinition extends TableDefinition<any, any>> = Types.Simplify<
137
+ Nullable<Pick<RowDecodedAll<TTableDefinition>, NullableColumnNames<TTableDefinition>>> &
138
+ Omit<RowDecodedAll<TTableDefinition>, NullableColumnNames<TTableDefinition>>
139
+ >
140
+
141
+ export type NullableColumnNames<TTableDefinition extends TableDefinition<any, any>> = FromColumns.NullableColumnNames<
142
+ TTableDefinition['columns']
143
+ >
144
+
145
+ export type Columns<TTableDefinition extends TableDefinition<any, any>> = {
146
+ [K in keyof TTableDefinition['columns']]: TTableDefinition['columns'][K]['columnType']
147
+ }
148
+
149
+ export type RowEncodeNonNullable<TTableDefinition extends TableDefinition<any, any>> = {
150
+ [K in keyof TTableDefinition['columns']]: Schema.Schema.Encoded<TTableDefinition['columns'][K]['schema']>
151
+ }
152
+
153
+ export type RowEncoded<TTableDefinition extends TableDefinition<any, any>> = Types.Simplify<
154
+ Nullable<Pick<RowEncodeNonNullable<TTableDefinition>, NullableColumnNames<TTableDefinition>>> &
155
+ Omit<RowEncodeNonNullable<TTableDefinition>, NullableColumnNames<TTableDefinition>>
156
+ >
157
+
158
+ // export type RowEncoded<TTableDefinition extends TableDefinition<any, any>> = NullableColumnNames<
159
+ // TTableDefinition['columns']
160
+ // >
161
+
162
+ // &
163
+ // Omit<RowEncodeNonNullable<TTableDefinition>, NullableColumnNames<TTableDefinition['columns']>>
164
+ // >
165
+
166
+ export type RowDecodedAll<TTableDefinition extends TableDefinition<any, any>> = {
167
+ [K in keyof TTableDefinition['columns']]: Schema.Schema.Type<TTableDefinition['columns'][K]['schema']>
168
+ }
169
+ }
170
+
171
+ export namespace FromColumns {
172
+ // TODO this sometimes doesn't preserve the order of columns
173
+ export type RowDecoded<TColumns extends Columns> = Types.Simplify<
174
+ Nullable<Pick<RowDecodedAll<TColumns>, NullableColumnNames<TColumns>>> &
175
+ Omit<RowDecodedAll<TColumns>, NullableColumnNames<TColumns>>
176
+ >
177
+
178
+ export type RowDecodedAll<TColumns extends Columns> = {
179
+ readonly [K in keyof TColumns]: Schema.Schema.Type<TColumns[K]['schema']>
180
+ }
181
+
182
+ export type RowEncodedAll<TColumns extends Columns> = {
183
+ readonly [K in keyof TColumns]: Schema.Schema.Encoded<TColumns[K]['schema']>
184
+ }
185
+
186
+ export type RowEncoded<TColumns extends Columns> = Types.Simplify<
187
+ Nullable<Pick<RowEncodeNonNullable<TColumns>, NullableColumnNames<TColumns>>> &
188
+ Omit<RowEncodeNonNullable<TColumns>, NullableColumnNames<TColumns>>
189
+ >
190
+
191
+ export type RowEncodeNonNullable<TColumns extends Columns> = {
192
+ readonly [K in keyof TColumns]: Schema.Schema.Encoded<TColumns[K]['schema']>
193
+ }
194
+
195
+ export type NullableColumnNames<TColumns extends Columns> = keyof {
196
+ // TODO double check why there is a `true` in the type
197
+ [K in keyof TColumns as TColumns[K] extends ColumnDefinition<any, true> ? K : never]: {}
198
+ }
199
+
200
+ export type RequiredInsertColumns<TColumns extends Columns> = {
201
+ [K in keyof TColumns as TColumns[K]['nullable'] extends true
202
+ ? never
203
+ : TColumns[K]['default'] extends Option.Some<any>
204
+ ? never
205
+ : K]: {}
206
+ }
207
+
208
+ export type RequiredInsertColumnNames<TColumns extends Columns> = keyof RequiredInsertColumns<TColumns>
209
+
210
+ export type RequiresInsertValues<TColumns extends Columns> =
211
+ RequiredInsertColumnNames<TColumns> extends never ? false : true
212
+
213
+ export type InsertRowDecoded<TColumns extends Columns> = Types.Simplify<
214
+ Pick<RowDecodedAll<TColumns>, RequiredInsertColumnNames<TColumns>> &
215
+ Partial<Omit<RowDecodedAll<TColumns>, RequiredInsertColumnNames<TColumns>>>
216
+ >
217
+
218
+ export type InsertRowEncoded<TColumns extends Columns> = Types.Simplify<
219
+ Pick<RowEncodedAll<TColumns>, RequiredInsertColumnNames<TColumns>> &
220
+ Partial<Omit<RowEncodedAll<TColumns>, RequiredInsertColumnNames<TColumns>>>
221
+ >
222
+ }