@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,444 @@
1
+ import { shouldNeverHappen } from '@livestore/utils'
2
+ import type { Option, Types } from '@livestore/utils/effect'
3
+ import { Schema, SchemaAST } from '@livestore/utils/effect'
4
+
5
+ import { SessionIdSymbol } from '../../../adapter-types.js'
6
+ import { sql } from '../../../util.js'
7
+ import type { EventDef, Materializer } from '../../EventDef.js'
8
+ import { defineEvent, defineMaterializer } from '../../EventDef.js'
9
+ import { SqliteDsl } from './db-schema/mod.js'
10
+ import type { QueryBuilder, QueryBuilderAst } from './query-builder/mod.js'
11
+ import { QueryBuilderAstSymbol, QueryBuilderTypeId } from './query-builder/mod.js'
12
+ import type { TableDef, TableDefBase } from './table-def.js'
13
+ import { table } from './table-def.js'
14
+
15
+ /**
16
+ * Special:
17
+ * - Synced across client sessions (e.g. tabs) but not across different clients
18
+ * - Derived setters
19
+ * - Emits client-only events
20
+ * - Has implicit setter-reducers
21
+ * - Similar to `React.useState` (except it's persisted)
22
+ *
23
+ * Careful:
24
+ * - When changing the table definitions in a non-backwards compatible way, the state might be lost without
25
+ * explicit reducers to handle the old auto-generated events
26
+ */
27
+ export const clientDocument = <
28
+ TName extends string,
29
+ TType,
30
+ TEncoded,
31
+ const TOptions extends ClientDocumentTableOptions.Input<NoInfer<TType>>,
32
+ >({
33
+ name,
34
+ schema: valueSchema,
35
+ ...inputOptions
36
+ }: {
37
+ name: TName
38
+ schema: Schema.Schema<TType, TEncoded>
39
+ } & TOptions): ClientDocumentTableDef<
40
+ TName,
41
+ TType,
42
+ TEncoded,
43
+ Types.Simplify<ClientDocumentTableOptions.WithDefaults<TOptions>>
44
+ > => {
45
+ const options = {
46
+ partialSet: inputOptions.partialSet ?? true,
47
+ default: {
48
+ id: inputOptions.default.id,
49
+ value: inputOptions.default.value,
50
+ },
51
+ } satisfies ClientDocumentTableOptions<TType>
52
+
53
+ const columns = {
54
+ id: SqliteDsl.text({ primaryKey: true }),
55
+ value: SqliteDsl.json({ schema: valueSchema }),
56
+ }
57
+
58
+ const tableDef = table({ name, columns })
59
+
60
+ // @ts-expect-error TODO properly type this
61
+ tableDef.options.isClientDocumentTable = true
62
+
63
+ const { eventDef: derivedSetEventDef, materializer: derivedSetMaterializer } = deriveEventAndMaterializer({
64
+ name,
65
+ valueSchema,
66
+ defaultValue: options.default.value,
67
+ partialSet: options.partialSet,
68
+ })
69
+
70
+ const setEventDef = (...args: any[]) => {
71
+ const [value, id = options.default.id] = args
72
+ return derivedSetEventDef({ id, value })
73
+ }
74
+
75
+ Object.defineProperty(setEventDef, 'name', { value: `${name}Set` })
76
+ Object.defineProperty(setEventDef, 'schema', {
77
+ value: Schema.Struct({
78
+ id: Schema.String,
79
+ value: options.partialSet ? Schema.partial(valueSchema) : valueSchema,
80
+ }).annotations({ title: `${name}Set:Args` }),
81
+ })
82
+ Object.defineProperty(setEventDef, 'options', { value: { derived: true, clientOnly: true, facts: undefined } })
83
+
84
+ const clientDocumentTableDefTrait: ClientDocumentTableDef.Trait<
85
+ TName,
86
+ TType,
87
+ TEncoded,
88
+ ClientDocumentTableOptions<TType>
89
+ > = {
90
+ get: makeGetQueryBuilder(() => clientDocumentTableDef) as any,
91
+ set: setEventDef as any,
92
+ Value: 'only-for-type-inference' as any,
93
+ default: options.default,
94
+ valueSchema,
95
+ [ClientDocumentTableDefSymbol]: {
96
+ derived: {
97
+ setEventDef: derivedSetEventDef as any,
98
+ setMaterializer: derivedSetMaterializer as any,
99
+ },
100
+ options,
101
+ },
102
+ }
103
+
104
+ const clientDocumentTableDef = {
105
+ ...tableDef,
106
+ ...clientDocumentTableDefTrait,
107
+ } as any
108
+
109
+ return clientDocumentTableDef
110
+ }
111
+
112
+ const mergeDefaultValues = <T>(defaultValues: T, explicitDefaultValues: T): T => {
113
+ if (
114
+ typeof defaultValues !== 'object' ||
115
+ typeof explicitDefaultValues !== 'object' ||
116
+ defaultValues === null ||
117
+ explicitDefaultValues === null
118
+ ) {
119
+ return explicitDefaultValues
120
+ }
121
+
122
+ return Object.keys(defaultValues as any).reduce((acc, key) => {
123
+ acc[key] = (explicitDefaultValues as any)[key] ?? (defaultValues as any)[key]
124
+ return acc
125
+ }, {} as any)
126
+ }
127
+
128
+ export const deriveEventAndMaterializer = ({
129
+ name,
130
+ valueSchema,
131
+ defaultValue,
132
+ partialSet,
133
+ }: {
134
+ name: string
135
+ valueSchema: Schema.Schema<any, any>
136
+ defaultValue: any
137
+ partialSet: boolean
138
+ }) => {
139
+ const derivedSetEventDef = defineEvent({
140
+ name: `${name}Set`,
141
+ schema: Schema.Struct({
142
+ id: Schema.Union(Schema.String, Schema.UniqueSymbolFromSelf(SessionIdSymbol)),
143
+ value: partialSet ? Schema.partial(valueSchema) : valueSchema,
144
+ }).annotations({ title: `${name}Set:Args` }),
145
+ clientOnly: true,
146
+ derived: true,
147
+ })
148
+
149
+ const derivedSetMaterializer = defineMaterializer(derivedSetEventDef, ({ id, value }) => {
150
+ if (id === SessionIdSymbol) {
151
+ return shouldNeverHappen(`SessionIdSymbol needs to be replaced before materializing the set event`)
152
+ }
153
+
154
+ // Override the full value if it's not an object or no partial set is allowed
155
+ const schemaProps = SchemaAST.getPropertySignatures(valueSchema.ast)
156
+ if (schemaProps.length === 0 || partialSet === false) {
157
+ const valueColJsonSchema = Schema.parseJson(valueSchema)
158
+ const encodedInsertValue = Schema.encodeSyncDebug(valueColJsonSchema)(value ?? defaultValue)
159
+ const encodedUpdateValue = Schema.encodeSyncDebug(valueColJsonSchema)(value)
160
+
161
+ return {
162
+ sql: `INSERT INTO '${name}' (id, value) VALUES (?, ?) ON CONFLICT (id) DO UPDATE SET value = ?`,
163
+ bindValues: [id, encodedInsertValue, encodedUpdateValue],
164
+ writeTables: new Set([name]),
165
+ }
166
+ } else {
167
+ const valueColJsonSchema = Schema.parseJson(Schema.partial(valueSchema))
168
+
169
+ const encodedInsertValue = Schema.encodeSyncDebug(valueColJsonSchema)(mergeDefaultValues(defaultValue, value))
170
+
171
+ let jsonSetSql = 'value'
172
+ const setBindValues: unknown[] = []
173
+
174
+ const keys = Object.keys(value)
175
+ const partialUpdateSchema = valueSchema.pipe(Schema.pick(...keys))
176
+ const encodedPartialUpdate = Schema.encodeSyncDebug(partialUpdateSchema)(value)
177
+
178
+ for (const key in encodedPartialUpdate) {
179
+ const encodedValueForKey = encodedPartialUpdate[key]
180
+ // Skipping undefined values
181
+ if (encodedValueForKey === undefined) {
182
+ continue
183
+ }
184
+ jsonSetSql = `json_set(${jsonSetSql}, ?, json(?))`
185
+ setBindValues.push(`$.${key}`, JSON.stringify(encodedValueForKey))
186
+ }
187
+
188
+ const onConflictClause =
189
+ setBindValues.length > 0
190
+ ? `ON CONFLICT (id) DO UPDATE SET value = ${jsonSetSql}`
191
+ : 'ON CONFLICT (id) DO NOTHING'
192
+
193
+ const sqlQuery = `
194
+ INSERT INTO '${name}' (id, value)
195
+ VALUES (?, ?)
196
+ ${onConflictClause}
197
+ `
198
+
199
+ return {
200
+ sql: sqlQuery,
201
+ bindValues: [id, encodedInsertValue, ...setBindValues],
202
+ writeTables: new Set([name]),
203
+ }
204
+ }
205
+ })
206
+
207
+ return { eventDef: derivedSetEventDef, materializer: derivedSetMaterializer }
208
+ }
209
+
210
+ export const tableIsClientDocumentTable = <TTableDef extends TableDefBase>(
211
+ tableDef: TTableDef,
212
+ ): tableDef is TTableDef & {
213
+ options: { isClientDocumentTable: true }
214
+ } & ClientDocumentTableDef.Trait<TTableDef['sqliteDef']['name'], any, any, any> =>
215
+ tableDef.options.isClientDocumentTable === true
216
+
217
+ const makeGetQueryBuilder = <TTableDef extends ClientDocumentTableDef<any, any, any, any>>(
218
+ getTableDef: () => TTableDef,
219
+ ): ClientDocumentTableDef.MakeGetQueryBuilder<any, any, any> => {
220
+ return ((...args: any[]) => {
221
+ const tableDef = getTableDef()
222
+
223
+ const [id = tableDef[ClientDocumentTableDefSymbol].options.default.id, options = {}] = args
224
+
225
+ const explicitDefaultValues = options.default ?? tableDef[ClientDocumentTableDefSymbol].options.default.value
226
+
227
+ const ast: QueryBuilderAst.RowQuery = {
228
+ _tag: 'RowQuery',
229
+ tableDef,
230
+ id,
231
+ explicitDefaultValues,
232
+ }
233
+
234
+ const query = sql`SELECT * FROM '${tableDef.sqliteDef.name}' WHERE id = ?`
235
+
236
+ return {
237
+ [QueryBuilderTypeId]: QueryBuilderTypeId,
238
+ [QueryBuilderAstSymbol]: ast,
239
+ ResultType: 'only-for-type-inference' as any,
240
+ asSql: () => ({ query, bindValues: [id] }),
241
+ toString: () => query.toString(),
242
+ ...({} as any), // Needed for type cast
243
+ }
244
+ }) as any
245
+ }
246
+
247
+ export type ClientDocumentTableOptions<TType> = {
248
+ partialSet: boolean
249
+ default: {
250
+ id: SessionIdSymbol | string | undefined
251
+ value: TType
252
+ }
253
+ }
254
+
255
+ export namespace ClientDocumentTableOptions {
256
+ export type Input<TType> = {
257
+ /**
258
+ * Whether to allow for partial set operations. Only applies if the schema is a struct.
259
+ *
260
+ * @default true
261
+ */
262
+ partialSet?: boolean
263
+ default: {
264
+ id?: SessionIdSymbol | string | undefined
265
+ value: TType
266
+ }
267
+ }
268
+
269
+ export type WithDefaults<TInput extends Input<any>> = {
270
+ partialSet: TInput['partialSet'] extends false ? false : true
271
+ default: {
272
+ id: TInput['default']['id'] extends string | SessionIdSymbol ? TInput['default']['id'] : undefined
273
+ value: TInput['default']['value']
274
+ }
275
+ }
276
+ }
277
+
278
+ export type ClientDocumentTableDef<
279
+ TName extends string,
280
+ TType,
281
+ TEncoded,
282
+ TOptions extends ClientDocumentTableOptions<TType>,
283
+ > = TableDef<
284
+ ClientDocumentTableDef.SqliteDef<TName, TType>,
285
+ {
286
+ isClientDocumentTable: true
287
+ }
288
+ > &
289
+ ClientDocumentTableDef.Trait<TName, TType, TEncoded, TOptions>
290
+
291
+ export namespace ClientDocumentTableDef {
292
+ export type Any = ClientDocumentTableDef<any, any, any, any>
293
+
294
+ export type SqliteDef<TName extends string, TType> = SqliteDsl.TableDefinition<
295
+ TName,
296
+ {
297
+ id: SqliteDsl.ColumnDefinition<string, string> & { default: Option.Some<string> }
298
+ value: SqliteDsl.ColumnDefinition<string, TType> & { default: Option.Some<TType> }
299
+ }
300
+ >
301
+
302
+ export type TableDefBase_<TName extends string, TType> = TableDefBase<
303
+ SqliteDef<TName, TType>,
304
+ {
305
+ isClientDocumentTable: true
306
+ }
307
+ >
308
+
309
+ export interface Trait<TName extends string, TType, TEncoded, TOptions extends ClientDocumentTableOptions<TType>> {
310
+ /**
311
+ * Get the current value of the client document table.
312
+ *
313
+ * @example
314
+ * ```ts
315
+ * const someDocumentTable = State.SQLite.clientDocument({
316
+ * name: 'SomeDocumentTable',
317
+ * schema: Schema.Struct({
318
+ * someField: Schema.String,
319
+ * }),
320
+ * default: { value: { someField: 'some-value' } },
321
+ * })
322
+ *
323
+ * const value$ = queryDb(someDocumentTable.get('some-id'))
324
+ *
325
+ * // When you've set a default id, you can omit the id argument
326
+ *
327
+ * const uiState = State.SQLite.clientDocument({
328
+ * name: 'UiState',
329
+ * schema: Schema.Struct({
330
+ * someField: Schema.String,
331
+ * }),
332
+ * default: { id: SessionIdSymbol, value: { someField: 'some-value' } },
333
+ * })
334
+ *
335
+ * const value$ = queryDb(uiState.get())
336
+ * ```
337
+ */
338
+ readonly get: MakeGetQueryBuilder<TName, TType, TOptions>
339
+ /**
340
+ * Derived event definition for setting the value of the client document table.
341
+ * If the document doesn't exist yet, the first .set event will create it.
342
+ *
343
+ * @example
344
+ * ```ts
345
+ * const someDocumentTable = State.SQLite.clientDocument({
346
+ * name: 'SomeDocumentTable',
347
+ * schema: Schema.Struct({
348
+ * someField: Schema.String,
349
+ * someOtherField: Schema.String,
350
+ * }),
351
+ * default: { value: { someField: 'some-default-value', someOtherField: 'some-other-default-value' } },
352
+ * })
353
+ *
354
+ * const setEventDef = store.commit(someDocumentTable.set({ someField: 'explicit-value' }, 'some-id'))
355
+ * // Will commit an event with the following payload:
356
+ * // { id: 'some-id', value: { someField: 'explicit-value', someOtherField: 'some-other-default-value' } }
357
+ * ```
358
+ *
359
+ * Similar to `.get`, you can omit the id argument if you've set a default id.
360
+ *
361
+ * @example
362
+ * ```ts
363
+ * const uiState = State.SQLite.clientDocument({
364
+ * name: 'UiState',
365
+ * schema: Schema.Struct({ someField: Schema.String }),
366
+ * default: { id: SessionIdSymbol, value: { someField: 'some-default-value' } },
367
+ * })
368
+ *
369
+ * const setEventDef = store.commit(uiState.set({ someField: 'explicit-value' }))
370
+ * // Will commit an event with the following payload:
371
+ * // { id: '...', value: { someField: 'explicit-value' } }
372
+ * // ^^^
373
+ * // Automatically replaced with the client session id
374
+ * ```
375
+ */
376
+ readonly set: SetEventDefLike<TName, TType, TOptions>
377
+ readonly Value: TType
378
+ readonly valueSchema: Schema.Schema<TType, TEncoded>
379
+ readonly default: TOptions['default']
380
+ readonly [ClientDocumentTableDefSymbol]: {
381
+ readonly options: TOptions
382
+ readonly derived: {
383
+ readonly setEventDef: SetEventDef<TName, TType, TOptions>
384
+ readonly setMaterializer: Materializer<SetEventDef<TName, TType, TOptions>>
385
+ }
386
+ }
387
+ }
388
+
389
+ export type GetOptions<TTableDef extends TraitAny> =
390
+ TTableDef extends ClientDocumentTableDef.Trait<any, any, any, infer TOptions> ? TOptions : never
391
+
392
+ export type TraitAny = Trait<any, any, any, any>
393
+
394
+ export type DefaultIdType<TTableDef extends TraitAny> =
395
+ TTableDef extends ClientDocumentTableDef.Trait<any, any, any, infer TOptions>
396
+ ? TOptions['default']['id'] extends SessionIdSymbol | string
397
+ ? TOptions['default']['id']
398
+ : never
399
+ : never
400
+
401
+ export type SetEventDefLike<TName extends string, TType, TOptions extends ClientDocumentTableOptions<TType>> =
402
+ // Helper to create partial event
403
+ (TOptions['default']['id'] extends undefined
404
+ ? (
405
+ args: TOptions['partialSet'] extends false ? TType : Partial<TType>,
406
+ id: string | SessionIdSymbol,
407
+ ) => { name: `${TName}Set`; args: { id: string; value: TType } }
408
+ : (
409
+ args: TOptions['partialSet'] extends false ? TType : Partial<TType>,
410
+ id?: string | SessionIdSymbol,
411
+ ) => { name: `${TName}Set`; args: { id: string; value: TType } }) & {
412
+ readonly name: `${TName}Set`
413
+ readonly schema: Schema.Schema<any>
414
+ readonly Event: {
415
+ readonly name: `${TName}Set`
416
+ readonly args: { id: string; value: TType }
417
+ }
418
+ readonly options: { derived: true; clientOnly: true; facts: undefined }
419
+ }
420
+
421
+ export type SetEventDef<TName extends string, TType, TOptions extends ClientDocumentTableOptions<TType>> = EventDef<
422
+ TName,
423
+ TOptions['partialSet'] extends false ? { id: string; value: TType } : { id: string; value: Partial<TType> },
424
+ any,
425
+ true
426
+ >
427
+
428
+ export type MakeGetQueryBuilder<
429
+ TName extends string,
430
+ TType,
431
+ TOptions extends ClientDocumentTableOptions<TType>,
432
+ > = TOptions extends ClientDocumentTableOptions<TType> & { default: { id: string | SessionIdSymbol } }
433
+ ? (
434
+ id?: TOptions['default']['id'] | SessionIdSymbol,
435
+ options?: { default: Partial<TType> },
436
+ ) => QueryBuilder<TType, ClientDocumentTableDef.TableDefBase_<TName, TType>, QueryBuilder.ApiFeature>
437
+ : (
438
+ id: string | SessionIdSymbol,
439
+ options?: { default: Partial<TType> },
440
+ ) => QueryBuilder<TType, ClientDocumentTableDef.TableDefBase_<TName, TType>, QueryBuilder.ApiFeature>
441
+ }
442
+
443
+ export const ClientDocumentTableDefSymbol = Symbol('ClientDocumentTableDef')
444
+ export type ClientDocumentTableDefSymbol = typeof ClientDocumentTableDefSymbol
@@ -0,0 +1,142 @@
1
+ import { type Option, Schema } from '@livestore/utils/effect'
2
+
3
+ import { hashCode } from '../hash.js'
4
+
5
+ export namespace ColumnType {
6
+ export type ColumnType = Text | Null | Real | Integer | Blob
7
+
8
+ export type Text = { _tag: 'text' }
9
+
10
+ export type Null = { _tag: 'null' }
11
+
12
+ export type Real = { _tag: 'real' }
13
+
14
+ export type Integer = { _tag: 'integer' }
15
+
16
+ export type Blob = { _tag: 'blob' }
17
+ }
18
+
19
+ export type Column = {
20
+ _tag: 'column'
21
+ name: string
22
+ type: ColumnType.ColumnType
23
+ primaryKey: boolean
24
+ nullable: boolean
25
+ default: Option.Option<any>
26
+ schema: Schema.Schema<any>
27
+ }
28
+
29
+ export const column = (props: Omit<Column, '_tag'>): Column => ({ _tag: 'column', ...props })
30
+
31
+ export type Index = {
32
+ _tag: 'index'
33
+ columns: ReadonlyArray<string>
34
+ name?: string
35
+ unique?: boolean
36
+ primaryKey?: boolean
37
+ }
38
+
39
+ export const index = (
40
+ columns: ReadonlyArray<string>,
41
+ name?: string,
42
+ unique?: boolean,
43
+ primaryKey?: boolean,
44
+ ): Index => ({
45
+ _tag: 'index',
46
+ columns,
47
+ name,
48
+ unique,
49
+ primaryKey,
50
+ })
51
+
52
+ export type ForeignKey = {
53
+ _tag: 'foreignKey'
54
+ references: {
55
+ table: string
56
+ columns: ReadonlyArray<string>
57
+ }
58
+ key: {
59
+ table: string
60
+ columns: ReadonlyArray<string>
61
+ }
62
+ columns: ReadonlyArray<string>
63
+ }
64
+
65
+ export type Table = {
66
+ _tag: 'table'
67
+ name: string
68
+ columns: ReadonlyArray<Column>
69
+ indexes: ReadonlyArray<Index>
70
+ }
71
+
72
+ export const table = (name: string, columns: ReadonlyArray<Column>, indexes: ReadonlyArray<Index>): Table => ({
73
+ _tag: 'table',
74
+ name,
75
+ columns,
76
+ indexes,
77
+ })
78
+
79
+ export type DbSchema = {
80
+ _tag: 'dbSchema'
81
+ tables: Table[]
82
+ }
83
+
84
+ export const dbSchema = (tables: Table[]): DbSchema => ({ _tag: 'dbSchema', tables })
85
+
86
+ /**
87
+ * NOTE we're only including SQLite-relevant information in the hash (which excludes the schema mapping)
88
+ */
89
+ export const hash = (obj: Table | Column | Index | ForeignKey | DbSchema): number =>
90
+ hashCode(JSON.stringify(trimInfoForHasing(obj)))
91
+
92
+ const trimInfoForHasing = (obj: Table | Column | Index | ForeignKey | DbSchema): Record<string, any> => {
93
+ switch (obj._tag) {
94
+ case 'table': {
95
+ return {
96
+ _tag: 'table',
97
+ name: obj.name,
98
+ columns: obj.columns.map((column) => trimInfoForHasing(column)),
99
+ indexes: obj.indexes.map((index) => trimInfoForHasing(index)),
100
+ }
101
+ }
102
+ case 'column': {
103
+ return {
104
+ _tag: 'column',
105
+ name: obj.name,
106
+ type: obj.type._tag,
107
+ primaryKey: obj.primaryKey,
108
+ nullable: obj.nullable,
109
+ default: obj.default,
110
+ }
111
+ }
112
+ case 'index': {
113
+ return {
114
+ _tag: 'index',
115
+ columns: obj.columns,
116
+ name: obj.name,
117
+ unique: obj.unique,
118
+ primaryKey: obj.primaryKey,
119
+ }
120
+ }
121
+ case 'foreignKey': {
122
+ return {
123
+ _tag: 'foreignKey',
124
+ references: obj.references,
125
+ key: obj.key,
126
+ columns: obj.columns,
127
+ }
128
+ }
129
+ case 'dbSchema': {
130
+ return {
131
+ _tag: 'dbSchema',
132
+ tables: obj.tables.map(trimInfoForHasing),
133
+ }
134
+ }
135
+ default: {
136
+ throw new Error(`Unreachable: ${obj}`)
137
+ }
138
+ }
139
+ }
140
+
141
+ export const structSchemaForTable = (tableDef: Table) =>
142
+ Schema.Struct(Object.fromEntries(tableDef.columns.map((column) => [column.name, column.schema])))
@@ -0,0 +1,13 @@
1
+ import type { DbSchema } from './sqlite.js'
2
+
3
+ // TODO
4
+ export const validate = (_dbSchema: DbSchema) => {
5
+ /*
6
+ TODO:
7
+
8
+ - ensure no duplicate table names
9
+ - ensure no duplicate column names within a table
10
+ - ensure no duplicate index names globally
11
+ - ...
12
+ */
13
+ }