@livestore/common 0.3.0-dev.11 → 0.3.0-dev.13

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 (280) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/__tests__/fixture.d.ts +21 -21
  3. package/dist/adapter-types.d.ts +41 -18
  4. package/dist/adapter-types.d.ts.map +1 -1
  5. package/dist/adapter-types.js +12 -0
  6. package/dist/adapter-types.js.map +1 -1
  7. package/dist/db-schema/ast/sqlite.d.ts +69 -0
  8. package/dist/db-schema/ast/sqlite.d.ts.map +1 -0
  9. package/dist/db-schema/ast/sqlite.js +71 -0
  10. package/dist/db-schema/ast/sqlite.js.map +1 -0
  11. package/dist/db-schema/ast/validate.d.ts +3 -0
  12. package/dist/db-schema/ast/validate.d.ts.map +1 -0
  13. package/dist/db-schema/ast/validate.js +12 -0
  14. package/dist/db-schema/ast/validate.js.map +1 -0
  15. package/dist/db-schema/dsl/field-defs.d.ts +90 -0
  16. package/dist/db-schema/dsl/field-defs.d.ts.map +1 -0
  17. package/dist/db-schema/dsl/field-defs.js +87 -0
  18. package/dist/db-schema/dsl/field-defs.js.map +1 -0
  19. package/dist/db-schema/dsl/field-defs.test.d.ts +2 -0
  20. package/dist/db-schema/dsl/field-defs.test.d.ts.map +1 -0
  21. package/dist/db-schema/dsl/field-defs.test.js +29 -0
  22. package/dist/db-schema/dsl/field-defs.test.js.map +1 -0
  23. package/dist/db-schema/dsl/index.d.ts +88 -0
  24. package/dist/db-schema/dsl/index.d.ts.map +1 -0
  25. package/dist/db-schema/dsl/index.js +35 -0
  26. package/dist/db-schema/dsl/index.js.map +1 -0
  27. package/dist/db-schema/dsl/mod.d.ts +90 -0
  28. package/dist/db-schema/dsl/mod.d.ts.map +1 -0
  29. package/dist/db-schema/dsl/mod.js +35 -0
  30. package/dist/db-schema/dsl/mod.js.map +1 -0
  31. package/dist/db-schema/dsl/sqlite/field-defs.d.ts +90 -0
  32. package/dist/db-schema/dsl/sqlite/field-defs.d.ts.map +1 -0
  33. package/dist/db-schema/dsl/sqlite/field-defs.js +86 -0
  34. package/dist/db-schema/dsl/sqlite/field-defs.js.map +1 -0
  35. package/dist/db-schema/dsl/sqlite/field-defs.test.d.ts +2 -0
  36. package/dist/db-schema/dsl/sqlite/field-defs.test.d.ts.map +1 -0
  37. package/dist/db-schema/dsl/sqlite/field-defs.test.js +29 -0
  38. package/dist/db-schema/dsl/sqlite/field-defs.test.js.map +1 -0
  39. package/dist/db-schema/dsl/sqlite/index.d.ts +88 -0
  40. package/dist/db-schema/dsl/sqlite/index.d.ts.map +1 -0
  41. package/dist/db-schema/dsl/sqlite/index.js +35 -0
  42. package/dist/db-schema/dsl/sqlite/index.js.map +1 -0
  43. package/dist/db-schema/hash.d.ts +2 -0
  44. package/dist/db-schema/hash.d.ts.map +1 -0
  45. package/dist/db-schema/hash.js +14 -0
  46. package/dist/db-schema/hash.js.map +1 -0
  47. package/dist/db-schema/index.d.ts +4 -0
  48. package/dist/db-schema/index.d.ts.map +1 -0
  49. package/dist/db-schema/index.js +6 -0
  50. package/dist/db-schema/index.js.map +1 -0
  51. package/dist/db-schema/mod.d.ts +3 -0
  52. package/dist/db-schema/mod.d.ts.map +1 -0
  53. package/dist/db-schema/mod.js +3 -0
  54. package/dist/db-schema/mod.js.map +1 -0
  55. package/dist/derived-mutations.d.ts +1 -1
  56. package/dist/derived-mutations.d.ts.map +1 -1
  57. package/dist/derived-mutations.js +3 -3
  58. package/dist/derived-mutations.js.map +1 -1
  59. package/dist/devtools/devtools-bridge.d.ts +10 -7
  60. package/dist/devtools/devtools-bridge.d.ts.map +1 -1
  61. package/dist/devtools/devtools-messages-client-session.d.ts +101 -28
  62. package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -1
  63. package/dist/devtools/devtools-messages-client-session.js +19 -3
  64. package/dist/devtools/devtools-messages-client-session.js.map +1 -1
  65. package/dist/devtools/devtools-messages-common.d.ts +24 -32
  66. package/dist/devtools/devtools-messages-common.d.ts.map +1 -1
  67. package/dist/devtools/devtools-messages-common.js +19 -10
  68. package/dist/devtools/devtools-messages-common.js.map +1 -1
  69. package/dist/devtools/devtools-messages-leader.d.ts +220 -56
  70. package/dist/devtools/devtools-messages-leader.d.ts.map +1 -1
  71. package/dist/devtools/devtools-messages-leader.js +57 -9
  72. package/dist/devtools/devtools-messages-leader.js.map +1 -1
  73. package/dist/devtools/devtools-messages.d.ts +2 -2
  74. package/dist/devtools/devtools-messages.d.ts.map +1 -1
  75. package/dist/devtools/devtools-messages.js +2 -2
  76. package/dist/devtools/devtools-messages.js.map +1 -1
  77. package/dist/index.d.ts +1 -1
  78. package/dist/index.d.ts.map +1 -1
  79. package/dist/index.js +1 -1
  80. package/dist/index.js.map +1 -1
  81. package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
  82. package/dist/leader-thread/LeaderSyncProcessor.js +50 -35
  83. package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
  84. package/dist/leader-thread/apply-mutation.d.ts.map +1 -1
  85. package/dist/leader-thread/apply-mutation.js +8 -6
  86. package/dist/leader-thread/apply-mutation.js.map +1 -1
  87. package/dist/leader-thread/connection.d.ts +31 -3
  88. package/dist/leader-thread/connection.d.ts.map +1 -1
  89. package/dist/leader-thread/connection.js +18 -3
  90. package/dist/leader-thread/connection.js.map +1 -1
  91. package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
  92. package/dist/leader-thread/leader-worker-devtools.js +56 -31
  93. package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
  94. package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
  95. package/dist/leader-thread/make-leader-thread-layer.js +23 -6
  96. package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
  97. package/dist/leader-thread/mutationlog.d.ts +1 -1
  98. package/dist/leader-thread/mutationlog.d.ts.map +1 -1
  99. package/dist/leader-thread/mutationlog.js +7 -5
  100. package/dist/leader-thread/mutationlog.js.map +1 -1
  101. package/dist/leader-thread/pull-queue-set.d.ts.map +1 -1
  102. package/dist/leader-thread/recreate-db.d.ts +4 -2
  103. package/dist/leader-thread/recreate-db.d.ts.map +1 -1
  104. package/dist/leader-thread/recreate-db.js +13 -8
  105. package/dist/leader-thread/recreate-db.js.map +1 -1
  106. package/dist/leader-thread/types.d.ts +22 -15
  107. package/dist/leader-thread/types.d.ts.map +1 -1
  108. package/dist/leader-thread/types.js +1 -3
  109. package/dist/leader-thread/types.js.map +1 -1
  110. package/dist/query-builder/api.d.ts +3 -3
  111. package/dist/query-builder/api.d.ts.map +1 -1
  112. package/dist/query-builder/impl.js.map +1 -1
  113. package/dist/query-builder/impl.test.js +16 -1
  114. package/dist/query-builder/impl.test.js.map +1 -1
  115. package/dist/query-info.d.ts +3 -3
  116. package/dist/query-info.d.ts.map +1 -1
  117. package/dist/rehydrate-from-mutationlog.d.ts.map +1 -1
  118. package/dist/rehydrate-from-mutationlog.js +8 -6
  119. package/dist/rehydrate-from-mutationlog.js.map +1 -1
  120. package/dist/schema/EventId.d.ts +10 -9
  121. package/dist/schema/EventId.d.ts.map +1 -1
  122. package/dist/schema/EventId.js +14 -11
  123. package/dist/schema/EventId.js.map +1 -1
  124. package/dist/schema/EventId.test.js +3 -3
  125. package/dist/schema/EventId.test.js.map +1 -1
  126. package/dist/schema/MutationEvent.d.ts +37 -12
  127. package/dist/schema/MutationEvent.d.ts.map +1 -1
  128. package/dist/schema/MutationEvent.js +20 -4
  129. package/dist/schema/MutationEvent.js.map +1 -1
  130. package/dist/schema/db-schema/ast/sqlite.d.ts +69 -0
  131. package/dist/schema/db-schema/ast/sqlite.d.ts.map +1 -0
  132. package/dist/schema/db-schema/ast/sqlite.js +71 -0
  133. package/dist/schema/db-schema/ast/sqlite.js.map +1 -0
  134. package/dist/schema/db-schema/ast/validate.d.ts +3 -0
  135. package/dist/schema/db-schema/ast/validate.d.ts.map +1 -0
  136. package/dist/schema/db-schema/ast/validate.js +12 -0
  137. package/dist/schema/db-schema/ast/validate.js.map +1 -0
  138. package/dist/schema/db-schema/dsl/field-defs.d.ts +90 -0
  139. package/dist/schema/db-schema/dsl/field-defs.d.ts.map +1 -0
  140. package/dist/schema/db-schema/dsl/field-defs.js +87 -0
  141. package/dist/schema/db-schema/dsl/field-defs.js.map +1 -0
  142. package/dist/schema/db-schema/dsl/field-defs.test.d.ts +2 -0
  143. package/dist/schema/db-schema/dsl/field-defs.test.d.ts.map +1 -0
  144. package/dist/schema/db-schema/dsl/field-defs.test.js +29 -0
  145. package/dist/schema/db-schema/dsl/field-defs.test.js.map +1 -0
  146. package/dist/schema/db-schema/dsl/mod.d.ts +88 -0
  147. package/dist/schema/db-schema/dsl/mod.d.ts.map +1 -0
  148. package/dist/schema/db-schema/dsl/mod.js +35 -0
  149. package/dist/schema/db-schema/dsl/mod.js.map +1 -0
  150. package/dist/schema/db-schema/hash.d.ts +2 -0
  151. package/dist/schema/db-schema/hash.d.ts.map +1 -0
  152. package/dist/schema/db-schema/hash.js +14 -0
  153. package/dist/schema/db-schema/hash.js.map +1 -0
  154. package/dist/schema/db-schema/mod.d.ts +3 -0
  155. package/dist/schema/db-schema/mod.d.ts.map +1 -0
  156. package/dist/schema/db-schema/mod.js +3 -0
  157. package/dist/schema/db-schema/mod.js.map +1 -0
  158. package/dist/schema/mod.d.ts +1 -0
  159. package/dist/schema/mod.d.ts.map +1 -1
  160. package/dist/schema/mod.js +1 -0
  161. package/dist/schema/mod.js.map +1 -1
  162. package/dist/schema/mutations.d.ts +4 -8
  163. package/dist/schema/mutations.d.ts.map +1 -1
  164. package/dist/schema/mutations.js +2 -2
  165. package/dist/schema/mutations.js.map +1 -1
  166. package/dist/schema/schema-helpers.js +1 -1
  167. package/dist/schema/schema-helpers.js.map +1 -1
  168. package/dist/schema/schema.d.ts +1 -1
  169. package/dist/schema/schema.d.ts.map +1 -1
  170. package/dist/schema/schema.js +1 -1
  171. package/dist/schema/schema.js.map +1 -1
  172. package/dist/schema/system-tables.d.ts +47 -29
  173. package/dist/schema/system-tables.d.ts.map +1 -1
  174. package/dist/schema/system-tables.js +10 -7
  175. package/dist/schema/system-tables.js.map +1 -1
  176. package/dist/schema/table-def.d.ts +18 -14
  177. package/dist/schema/table-def.d.ts.map +1 -1
  178. package/dist/schema/table-def.js +3 -4
  179. package/dist/schema/table-def.js.map +1 -1
  180. package/dist/schema-management/migrations.d.ts +3 -3
  181. package/dist/schema-management/migrations.d.ts.map +1 -1
  182. package/dist/schema-management/migrations.js +7 -2
  183. package/dist/schema-management/migrations.js.map +1 -1
  184. package/dist/sql-queries/sql-queries.d.ts +1 -1
  185. package/dist/sql-queries/sql-queries.d.ts.map +1 -1
  186. package/dist/sql-queries/sql-queries.js.map +1 -1
  187. package/dist/sql-queries/sql-query-builder.d.ts +1 -1
  188. package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
  189. package/dist/sql-queries/sql-query-builder.js.map +1 -1
  190. package/dist/sql-queries/types.d.ts +2 -1
  191. package/dist/sql-queries/types.d.ts.map +1 -1
  192. package/dist/sql-queries/types.js.map +1 -1
  193. package/dist/sync/ClientSessionSyncProcessor.d.ts +3 -5
  194. package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
  195. package/dist/sync/ClientSessionSyncProcessor.js +38 -12
  196. package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
  197. package/dist/sync/next/facts.js +1 -1
  198. package/dist/sync/next/facts.js.map +1 -1
  199. package/dist/sync/next/history-dag-common.d.ts +2 -0
  200. package/dist/sync/next/history-dag-common.d.ts.map +1 -1
  201. package/dist/sync/next/history-dag-common.js +3 -1
  202. package/dist/sync/next/history-dag-common.js.map +1 -1
  203. package/dist/sync/next/history-dag.d.ts.map +1 -1
  204. package/dist/sync/next/history-dag.js +1 -1
  205. package/dist/sync/next/history-dag.js.map +1 -1
  206. package/dist/sync/next/rebase-events.d.ts +3 -1
  207. package/dist/sync/next/rebase-events.d.ts.map +1 -1
  208. package/dist/sync/next/rebase-events.js +5 -3
  209. package/dist/sync/next/rebase-events.js.map +1 -1
  210. package/dist/sync/next/test/compact-events.calculator.test.js +12 -12
  211. package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
  212. package/dist/sync/next/test/compact-events.test.js +43 -43
  213. package/dist/sync/next/test/compact-events.test.js.map +1 -1
  214. package/dist/sync/next/test/mutation-fixtures.d.ts +11 -11
  215. package/dist/sync/next/test/mutation-fixtures.d.ts.map +1 -1
  216. package/dist/sync/next/test/mutation-fixtures.js +12 -10
  217. package/dist/sync/next/test/mutation-fixtures.js.map +1 -1
  218. package/dist/sync/sync.d.ts +2 -2
  219. package/dist/sync/syncstate.d.ts +9 -9
  220. package/dist/sync/syncstate.js +6 -6
  221. package/dist/sync/syncstate.js.map +1 -1
  222. package/dist/sync/syncstate.test.js +18 -16
  223. package/dist/sync/syncstate.test.js.map +1 -1
  224. package/dist/version.d.ts +1 -1
  225. package/dist/version.js +1 -1
  226. package/package.json +2 -3
  227. package/src/adapter-types.ts +35 -17
  228. package/src/derived-mutations.ts +4 -4
  229. package/src/devtools/devtools-bridge.ts +10 -7
  230. package/src/devtools/devtools-messages-client-session.ts +26 -10
  231. package/src/devtools/devtools-messages-common.ts +37 -8
  232. package/src/devtools/devtools-messages-leader.ts +78 -16
  233. package/src/devtools/devtools-messages.ts +2 -2
  234. package/src/index.ts +1 -1
  235. package/src/leader-thread/LeaderSyncProcessor.ts +59 -38
  236. package/src/leader-thread/apply-mutation.ts +15 -5
  237. package/src/leader-thread/connection.ts +48 -3
  238. package/src/leader-thread/leader-worker-devtools.ts +85 -35
  239. package/src/leader-thread/make-leader-thread-layer.ts +29 -9
  240. package/src/leader-thread/mutationlog.ts +8 -6
  241. package/src/leader-thread/recreate-db.ts +19 -10
  242. package/src/leader-thread/types.ts +22 -15
  243. package/src/query-builder/api.ts +4 -4
  244. package/src/query-builder/impl.test.ts +22 -1
  245. package/src/query-builder/impl.ts +2 -2
  246. package/src/query-info.ts +3 -3
  247. package/src/rehydrate-from-mutationlog.ts +8 -6
  248. package/src/schema/EventId.test.ts +3 -3
  249. package/src/schema/EventId.ts +20 -16
  250. package/src/schema/MutationEvent.ts +31 -6
  251. package/src/schema/db-schema/ast/sqlite.ts +142 -0
  252. package/src/schema/db-schema/ast/validate.ts +13 -0
  253. package/src/schema/db-schema/dsl/__snapshots__/field-defs.test.ts.snap +206 -0
  254. package/src/schema/db-schema/dsl/field-defs.test.ts +35 -0
  255. package/src/schema/db-schema/dsl/field-defs.ts +242 -0
  256. package/src/schema/db-schema/dsl/mod.ts +195 -0
  257. package/src/schema/db-schema/hash.ts +14 -0
  258. package/src/schema/db-schema/mod.ts +2 -0
  259. package/src/schema/mod.ts +1 -0
  260. package/src/schema/mutations.ts +6 -19
  261. package/src/schema/schema-helpers.ts +1 -1
  262. package/src/schema/schema.ts +2 -2
  263. package/src/schema/system-tables.ts +10 -7
  264. package/src/schema/table-def.ts +17 -16
  265. package/src/schema-management/migrations.ts +10 -6
  266. package/src/sql-queries/sql-queries.ts +1 -1
  267. package/src/sql-queries/sql-query-builder.ts +1 -2
  268. package/src/sql-queries/types.ts +3 -1
  269. package/src/sync/ClientSessionSyncProcessor.ts +44 -14
  270. package/src/sync/next/facts.ts +1 -1
  271. package/src/sync/next/history-dag-common.ts +5 -1
  272. package/src/sync/next/history-dag.ts +1 -1
  273. package/src/sync/next/rebase-events.ts +8 -2
  274. package/src/sync/next/test/compact-events.calculator.test.ts +12 -12
  275. package/src/sync/next/test/compact-events.test.ts +43 -43
  276. package/src/sync/next/test/mutation-fixtures.ts +16 -12
  277. package/src/sync/syncstate.test.ts +19 -17
  278. package/src/sync/syncstate.ts +6 -6
  279. package/src/version.ts +1 -1
  280. package/tsconfig.json +1 -1
@@ -1,17 +1,16 @@
1
- import type { Nullable, PrettifyFlat } from '@livestore/db-schema'
2
- import { SqliteDsl } from '@livestore/db-schema'
1
+ import type { Nullable } from '@livestore/utils'
3
2
  import { shouldNeverHappen } from '@livestore/utils'
3
+ import type { Types } from '@livestore/utils/effect'
4
4
  import { ReadonlyRecord, Schema } from '@livestore/utils/effect'
5
5
 
6
6
  import type { DerivedMutationHelperFns } from '../derived-mutations.js'
7
7
  import { makeDerivedMutationDefsForTable } from '../derived-mutations.js'
8
8
  import type { QueryBuilder } from '../query-builder/mod.js'
9
9
  import { makeQueryBuilder } from '../query-builder/mod.js'
10
+ import { SqliteDsl } from './db-schema/mod.js'
10
11
 
11
12
  export const { blob, boolean, column, datetime, integer, isColumnDefinition, json, real, text } = SqliteDsl
12
13
 
13
- export { SqliteDsl } from '@livestore/db-schema'
14
-
15
14
  export type StateType = 'singleton' | 'dynamic'
16
15
 
17
16
  export type DefaultSqliteTableDef = SqliteDsl.TableDefinition<string, SqliteDsl.Columns>
@@ -61,7 +60,7 @@ export type TableOptionsInput = Partial<{
61
60
  | boolean
62
61
  | {
63
62
  enabled: true
64
- localOnly?: boolean
63
+ clientOnly?: boolean
65
64
  }
66
65
  }>
67
66
 
@@ -115,7 +114,7 @@ export type TableOptions = {
115
114
  /**
116
115
  * When set to true, the mutations won't be synced over the network
117
116
  */
118
- localOnly: boolean
117
+ clientOnly: boolean
119
118
  }
120
119
 
121
120
  /** Derived based on whether the table definition has one or more columns (besides the `id` column) */
@@ -153,12 +152,12 @@ export const table = <
153
152
  disableAutomaticIdColumn: options?.disableAutomaticIdColumn ?? false,
154
153
  deriveMutations:
155
154
  options?.deriveMutations === true
156
- ? { enabled: true as const, localOnly: false }
155
+ ? { enabled: true as const, clientOnly: false }
157
156
  : options?.deriveMutations === false
158
157
  ? { enabled: false as const }
159
158
  : options?.deriveMutations === undefined
160
159
  ? { enabled: false as const }
161
- : { enabled: true as const, localOnly: options.deriveMutations.localOnly ?? false },
160
+ : { enabled: true as const, clientOnly: options.deriveMutations.clientOnly ?? false },
162
161
  isSingleColumn: SqliteDsl.isColumnDefinition(columnOrColumns) === true,
163
162
  requiredInsertColumnNames: 'type-level-only',
164
163
  }
@@ -234,7 +233,7 @@ export const table = <
234
233
  export const tableHasDerivedMutations = <TTableDef extends TableDefBase>(
235
234
  tableDef: TTableDef,
236
235
  ): tableDef is TTableDef & {
237
- options: { deriveMutations: { enabled: true; localOnly: boolean } }
236
+ options: { deriveMutations: { enabled: true; clientOnly: boolean } }
238
237
  } & DerivedMutationHelperFns<TTableDef['sqliteDef']['columns'], TTableDef['options']> =>
239
238
  tableDef.options.deriveMutations.enabled === true
240
239
 
@@ -242,6 +241,8 @@ export const tableIsSingleton = <TTableDef extends TableDefBase>(
242
241
  tableDef: TTableDef,
243
242
  ): tableDef is TTableDef & { options: { isSingleton: true } } => tableDef.options.isSingleton === true
244
243
 
244
+ export type PrettifyFlat<T> = T extends infer U ? { [K in keyof U]: U[K] } : never
245
+
245
246
  type SqliteTableDefForInput<
246
247
  TName extends string,
247
248
  TColumns extends SqliteDsl.Columns | SqliteDsl.ColumnDefinition<any, any>,
@@ -268,13 +269,13 @@ type WithDefaults<
268
269
  isSingleton: TOptionsInput['isSingleton'] extends true ? true : false
269
270
  disableAutomaticIdColumn: TOptionsInput['disableAutomaticIdColumn'] extends true ? true : false
270
271
  deriveMutations: TOptionsInput['deriveMutations'] extends true
271
- ? { enabled: true; localOnly: boolean }
272
+ ? { enabled: true; clientOnly: boolean }
272
273
  : TOptionsInput['deriveMutations'] extends false
273
274
  ? { enabled: false }
274
- : TOptionsInput['deriveMutations'] extends { enabled: true; localOnly?: boolean }
275
+ : TOptionsInput['deriveMutations'] extends { enabled: true; clientOnly?: boolean }
275
276
  ? {
276
277
  enabled: true
277
- localOnly: TOptionsInput['deriveMutations']['localOnly'] extends true ? true : false
278
+ clientOnly: TOptionsInput['deriveMutations']['clientOnly'] extends true ? true : false
278
279
  }
279
280
  : never
280
281
  isSingleColumn: SqliteDsl.IsSingleColumn<TColumns>
@@ -283,7 +284,7 @@ type WithDefaults<
283
284
 
284
285
  export namespace FromTable {
285
286
  // TODO this sometimes doesn't preserve the order of columns
286
- export type RowDecoded<TTableDef extends TableDefBase> = PrettifyFlat<
287
+ export type RowDecoded<TTableDef extends TableDefBase> = Types.Simplify<
287
288
  Nullable<Pick<RowDecodedAll<TTableDef>, NullableColumnNames<TTableDef>>> &
288
289
  Omit<RowDecodedAll<TTableDef>, NullableColumnNames<TTableDef>>
289
290
  >
@@ -302,7 +303,7 @@ export namespace FromTable {
302
303
  >
303
304
  }
304
305
 
305
- export type RowEncoded<TTableDef extends TableDefBase> = PrettifyFlat<
306
+ export type RowEncoded<TTableDef extends TableDefBase> = Types.Simplify<
306
307
  Nullable<Pick<RowEncodeNonNullable<TTableDef>, NullableColumnNames<TTableDef>>> &
307
308
  Omit<RowEncodeNonNullable<TTableDef>, NullableColumnNames<TTableDef>>
308
309
  >
@@ -314,7 +315,7 @@ export namespace FromTable {
314
315
 
315
316
  export namespace FromColumns {
316
317
  // TODO this sometimes doesn't preserve the order of columns
317
- export type RowDecoded<TColumns extends SqliteDsl.Columns> = PrettifyFlat<
318
+ export type RowDecoded<TColumns extends SqliteDsl.Columns> = Types.Simplify<
318
319
  Nullable<Pick<RowDecodedAll<TColumns>, NullableColumnNames<TColumns>>> &
319
320
  Omit<RowDecodedAll<TColumns>, NullableColumnNames<TColumns>>
320
321
  >
@@ -323,7 +324,7 @@ export namespace FromColumns {
323
324
  [K in keyof TColumns]: Schema.Schema.Type<TColumns[K]['schema']>
324
325
  }
325
326
 
326
- export type RowEncoded<TColumns extends SqliteDsl.Columns> = PrettifyFlat<
327
+ export type RowEncoded<TColumns extends SqliteDsl.Columns> = Types.Simplify<
327
328
  Nullable<Pick<RowEncodeNonNullable<TColumns>, NullableColumnNames<TColumns>>> &
328
329
  Omit<RowEncodeNonNullable<TColumns>, NullableColumnNames<TColumns>>
329
330
  >
@@ -1,8 +1,8 @@
1
- import { SqliteAst, SqliteDsl } from '@livestore/db-schema'
2
1
  import { memoizeByStringifyArgs } from '@livestore/utils'
3
2
  import { Effect, Schema as EffectSchema } from '@livestore/utils/effect'
4
3
 
5
- import type { SqliteDb } from '../adapter-types.js'
4
+ import type { MigrationsReport, MigrationsReportEntry, SqliteDb, UnexpectedError } from '../adapter-types.js'
5
+ import { SqliteAst, SqliteDsl } from '../schema/db-schema/mod.js'
6
6
  import type { LiveStoreSchema } from '../schema/mod.js'
7
7
  import type { SchemaMetaRow, SchemaMutationsMetaRow } from '../schema/system-tables.js'
8
8
  import {
@@ -54,7 +54,7 @@ export const migrateDb = ({
54
54
  db: SqliteDb
55
55
  schema: LiveStoreSchema
56
56
  onProgress?: (opts: { done: number; total: number }) => Effect.Effect<void>
57
- }) =>
57
+ }): Effect.Effect<MigrationsReport, UnexpectedError> =>
58
58
  Effect.gen(function* () {
59
59
  yield* migrateTable({
60
60
  db,
@@ -81,6 +81,7 @@ export const migrateDb = ({
81
81
 
82
82
  const tablesToMigrate = new Set<{ tableAst: SqliteAst.Table; schemaHash: number }>()
83
83
 
84
+ const migrationsReportEntries: MigrationsReportEntry[] = []
84
85
  for (const tableDef of tableDefs) {
85
86
  const tableAst = tableDef.sqliteDef.ast
86
87
  const tableName = tableAst.name
@@ -90,9 +91,10 @@ export const migrateDb = ({
90
91
  if (schemaHash !== dbSchemaHash) {
91
92
  tablesToMigrate.add({ tableAst, schemaHash })
92
93
 
93
- console.log(
94
- `Schema hash mismatch for table '${tableName}' (DB: ${dbSchemaHash}, expected: ${schemaHash}), migrating table...`,
95
- )
94
+ migrationsReportEntries.push({
95
+ tableName,
96
+ hashes: { expected: schemaHash, actual: dbSchemaHash },
97
+ })
96
98
  }
97
99
  }
98
100
 
@@ -107,6 +109,8 @@ export const migrateDb = ({
107
109
  yield* onProgress({ done: processedTables, total: tablesCount })
108
110
  }
109
111
  }
112
+
113
+ return { migrations: migrationsReportEntries }
110
114
  })
111
115
 
112
116
  export const migrateTable = ({
@@ -1,7 +1,7 @@
1
- import type { SqliteDsl } from '@livestore/db-schema'
2
1
  import { shouldNeverHappen } from '@livestore/utils'
3
2
  import { pipe, ReadonlyArray, Schema, TreeFormatter } from '@livestore/utils/effect'
4
3
 
4
+ import type { SqliteDsl } from '../schema/db-schema/mod.js'
5
5
  import { sql } from '../util.js'
6
6
  import { objectEntries } from './misc.js'
7
7
  import * as ClientTypes from './types.js'
@@ -1,5 +1,4 @@
1
- import type { SqliteDsl } from '@livestore/db-schema'
2
-
1
+ import type { SqliteDsl } from '../schema/db-schema/mod.js'
3
2
  import type { BindValues } from './sql-queries.js'
4
3
  import * as SqlQueries from './sql-queries.js'
5
4
  import type * as ClientTypes from './types.js'
@@ -1,6 +1,8 @@
1
- import type { Prettify, SqliteDsl } from '@livestore/db-schema'
1
+ import type { Prettify } from '@livestore/utils'
2
2
  import type { Schema } from '@livestore/utils/effect'
3
3
 
4
+ import type { SqliteDsl } from '../schema/db-schema/mod.js'
5
+
4
6
  export type DecodedValuesForTableAll<TSchema extends SqliteDsl.DbSchema, TTableName extends keyof TSchema> = {
5
7
  [K in keyof GetColumns<TSchema, TTableName>]: Schema.Schema.Type<GetColumn<TSchema, TTableName, K>['schema']>
6
8
  }
@@ -1,13 +1,13 @@
1
1
  import { LS_DEV, shouldNeverHappen, TRACE_VERBOSE } from '@livestore/utils'
2
2
  import type { Runtime, Scope } from '@livestore/utils/effect'
3
- import { Effect, Schema, Stream } from '@livestore/utils/effect'
3
+ import { Effect, Queue, Schema, Stream, Subscribable } from '@livestore/utils/effect'
4
4
  import * as otel from '@opentelemetry/api'
5
5
 
6
6
  import type { ClientSession, UnexpectedError } from '../adapter-types.js'
7
7
  import * as EventId from '../schema/EventId.js'
8
8
  import { type LiveStoreSchema } from '../schema/mod.js'
9
9
  import * as MutationEvent from '../schema/MutationEvent.js'
10
- import { SyncState, updateSyncState } from './syncstate.js'
10
+ import * as SyncState from './syncstate.js'
11
11
 
12
12
  /**
13
13
  * Rebase behaviour:
@@ -44,18 +44,19 @@ export const makeClientSessionSyncProcessor = ({
44
44
  const mutationEventSchema = MutationEvent.makeMutationEventSchemaMemo(schema)
45
45
 
46
46
  const syncStateRef = {
47
- current: new SyncState({
48
- localHead: clientSession.leaderThread.mutations.initialMutationEventId,
49
- upstreamHead: clientSession.leaderThread.mutations.initialMutationEventId,
47
+ current: new SyncState.SyncState({
48
+ localHead: clientSession.leaderThread.initialState.leaderHead,
49
+ upstreamHead: clientSession.leaderThread.initialState.leaderHead,
50
50
  pending: [],
51
51
  // TODO init rollbackTail from leader to be ready for backend rebasing
52
52
  rollbackTail: [],
53
53
  }),
54
54
  }
55
55
 
56
+ const syncStateUpdateQueue = Queue.unbounded<SyncState.SyncState>().pipe(Effect.runSync)
56
57
  const isLocalEvent = (mutationEventEncoded: MutationEvent.EncodedWithMeta) => {
57
58
  const mutationDef = schema.mutations.get(mutationEventEncoded.mutation)!
58
- return mutationDef.options.localOnly
59
+ return mutationDef.options.clientOnly
59
60
  }
60
61
 
61
62
  const push: ClientSessionSyncProcessor['push'] = (batch, { otelContext }) => {
@@ -64,14 +65,19 @@ export const makeClientSessionSyncProcessor = ({
64
65
  let baseEventId = syncStateRef.current.localHead
65
66
  const encodedMutationEvents = batch.map((mutationEvent) => {
66
67
  const mutationDef = schema.mutations.get(mutationEvent.mutation)!
67
- const nextIdPair = EventId.nextPair(baseEventId, mutationDef.options.localOnly)
68
+ const nextIdPair = EventId.nextPair(baseEventId, mutationDef.options.clientOnly)
68
69
  baseEventId = nextIdPair.id
69
70
  return new MutationEvent.EncodedWithMeta(
70
- Schema.encodeUnknownSync(mutationEventSchema)({ ...mutationEvent, ...nextIdPair }),
71
+ Schema.encodeUnknownSync(mutationEventSchema)({
72
+ ...mutationEvent,
73
+ ...nextIdPair,
74
+ clientId: clientSession.clientId,
75
+ sessionId: clientSession.sessionId,
76
+ }),
71
77
  )
72
78
  })
73
79
 
74
- const updateResult = updateSyncState({
80
+ const updateResult = SyncState.updateSyncState({
75
81
  syncState: syncStateRef.current,
76
82
  payload: { _tag: 'local-push', newEvents: encodedMutationEvents },
77
83
  isLocalEvent,
@@ -88,6 +94,7 @@ export const makeClientSessionSyncProcessor = ({
88
94
  }
89
95
 
90
96
  syncStateRef.current = updateResult.newSyncState
97
+ syncStateUpdateQueue.offer(updateResult.newSyncState).pipe(Effect.runSync)
91
98
 
92
99
  const writeTables = new Set<string>()
93
100
  for (const mutationEvent of updateResult.newEvents) {
@@ -111,6 +118,21 @@ export const makeClientSessionSyncProcessor = ({
111
118
  const otelContext = otel.trace.setSpan(otel.context.active(), span)
112
119
 
113
120
  const boot: ClientSessionSyncProcessor['boot'] = Effect.gen(function* () {
121
+ // eslint-disable-next-line unicorn/prefer-global-this
122
+ if (typeof window !== 'undefined') {
123
+ const onBeforeUnload = (event: BeforeUnloadEvent) => {
124
+ if (syncStateRef.current.pending.length > 0) {
125
+ // Trigger the default browser dialog
126
+ event.preventDefault()
127
+ }
128
+ }
129
+
130
+ yield* Effect.acquireRelease(
131
+ Effect.sync(() => window.addEventListener('beforeunload', onBeforeUnload)),
132
+ () => Effect.sync(() => window.removeEventListener('beforeunload', onBeforeUnload)),
133
+ )
134
+ }
135
+
114
136
  yield* clientSession.leaderThread.mutations.pull.pipe(
115
137
  Stream.tap(({ payload, remaining }) =>
116
138
  Effect.gen(function* () {
@@ -119,7 +141,7 @@ export const makeClientSessionSyncProcessor = ({
119
141
  yield* clientSession.devtools.pullLatch.await
120
142
  }
121
143
 
122
- const updateResult = updateSyncState({
144
+ const updateResult = SyncState.updateSyncState({
123
145
  syncState: syncStateRef.current,
124
146
  payload,
125
147
  isLocalEvent,
@@ -132,6 +154,7 @@ export const makeClientSessionSyncProcessor = ({
132
154
  }
133
155
 
134
156
  syncStateRef.current = updateResult.newSyncState
157
+ syncStateUpdateQueue.offer(updateResult.newSyncState).pipe(Effect.runSync)
135
158
 
136
159
  if (updateResult._tag === 'rebase') {
137
160
  span.addEvent('pull:rebase', {
@@ -143,11 +166,11 @@ export const makeClientSessionSyncProcessor = ({
143
166
  remaining,
144
167
  })
145
168
  if (LS_DEV) {
146
- console.debug(
169
+ Effect.logDebug(
147
170
  'pull:rebase: rollback',
148
171
  updateResult.eventsToRollback.length,
149
172
  ...updateResult.eventsToRollback.map((_) => _.toJSON()),
150
- )
173
+ ).pipe(Effect.provide(runtime), Effect.runSync)
151
174
  }
152
175
 
153
176
  for (let i = updateResult.eventsToRollback.length - 1; i >= 0; i--) {
@@ -197,7 +220,14 @@ export const makeClientSessionSyncProcessor = ({
197
220
  return {
198
221
  push,
199
222
  boot,
200
- syncStateRef,
223
+ syncState: Subscribable.make({
224
+ get: Effect.gen(function* () {
225
+ const syncState = syncStateRef.current
226
+ if (syncStateRef === undefined) return shouldNeverHappen('Not initialized')
227
+ return syncState
228
+ }),
229
+ changes: Stream.fromQueue(syncStateUpdateQueue),
230
+ }),
201
231
  } satisfies ClientSessionSyncProcessor
202
232
  }
203
233
 
@@ -210,5 +240,5 @@ export interface ClientSessionSyncProcessor {
210
240
  }
211
241
  boot: Effect.Effect<void, UnexpectedError, Scope.Scope>
212
242
 
213
- syncStateRef: { current: SyncState }
243
+ syncState: Subscribable.Subscribable<SyncState.SyncState>
214
244
  }
@@ -231,5 +231,5 @@ export const compareEventIds = (a: EventId.EventId, b: EventId.EventId) => {
231
231
  if (a.global !== b.global) {
232
232
  return a.global - b.global
233
233
  }
234
- return a.local - b.local
234
+ return a.client - b.client
235
235
  }
@@ -20,7 +20,7 @@ export const emptyHistoryDag = (): HistoryDag =>
20
20
  })
21
21
 
22
22
  // TODO consider making `ROOT_ID` parent to itself
23
- export const rootParentId = EventId.make({ global: EventId.ROOT.global - 1, local: EventId.localDefault })
23
+ export const rootParentId = EventId.make({ global: EventId.ROOT.global - 1, client: EventId.clientDefault })
24
24
 
25
25
  export type HistoryDagNode = {
26
26
  id: EventId.EventId
@@ -30,6 +30,8 @@ export type HistoryDagNode = {
30
30
  /** Facts are being used for conflict detection and history compaction */
31
31
  factsGroup: MutationEventFactsGroup
32
32
  meta?: any
33
+ clientId: string
34
+ sessionId: string | undefined
33
35
  }
34
36
 
35
37
  export const rootEventNode: HistoryDagNode = {
@@ -39,6 +41,8 @@ export const rootEventNode: HistoryDagNode = {
39
41
  mutation: '__Root__',
40
42
  args: {},
41
43
  factsGroup: { modifySet: new Map(), modifyUnset: new Map(), depRequire: new Map(), depRead: new Map() },
44
+ clientId: 'root',
45
+ sessionId: undefined,
42
46
  }
43
47
 
44
48
  export const EMPTY_FACT_VALUE = Symbol('EMPTY_FACT_VALUE')
@@ -3,7 +3,7 @@ import { factsToString, validateFacts } from './facts.js'
3
3
  import { emptyHistoryDag, type HistoryDagNode, rootParentId } from './history-dag-common.js'
4
4
 
5
5
  export const eventIdToString = (eventId: EventId.EventId) =>
6
- eventId.local === 0 ? eventId.global.toString() : `${eventId.global}.${eventId.local}`
6
+ eventId.client === 0 ? eventId.global.toString() : `${eventId.global}.${eventId.client}`
7
7
 
8
8
  export const historyDagFromNodes = (dagNodes: HistoryDagNode[], options?: { skipFactsCheck: boolean }) => {
9
9
  if (options?.skipFactsCheck !== true) {
@@ -43,11 +43,15 @@ export const rebaseEvents = ({
43
43
  pendingLocalEvents,
44
44
  newRemoteEvents,
45
45
  currentFactsSnapshot,
46
+ clientId,
47
+ sessionId,
46
48
  }: {
47
49
  pendingLocalEvents: HistoryDagNode[]
48
50
  newRemoteEvents: HistoryDagNode[]
49
51
  rebaseFn: RebaseFn
50
52
  currentFactsSnapshot: MutationEventFactsSnapshot
53
+ clientId: string
54
+ sessionId: string | undefined
51
55
  }): ReadonlyArray<MutationEvent.AnyDecoded> => {
52
56
  const initialSnapshot = new Map(currentFactsSnapshot)
53
57
  applyFactGroups(
@@ -89,10 +93,12 @@ export const rebaseEvents = ({
89
93
  return rebasedLocalEvents.map(
90
94
  (event, index) =>
91
95
  ({
92
- id: EventId.make({ global: headGlobalId + index + 1, local: EventId.localDefault }),
93
- parentId: EventId.make({ global: headGlobalId + index, local: EventId.localDefault }),
96
+ id: EventId.make({ global: headGlobalId + index + 1, client: EventId.clientDefault }),
97
+ parentId: EventId.make({ global: headGlobalId + index, client: EventId.clientDefault }),
94
98
  mutation: event.mutation,
95
99
  args: event.args,
100
+ clientId,
101
+ sessionId,
96
102
  }) satisfies MutationEvent.AnyDecoded,
97
103
  )
98
104
  }
@@ -10,7 +10,7 @@ import { toEventNodes } from './mutation-fixtures.js'
10
10
  expect.addSnapshotSerializer(customSerializer)
11
11
 
12
12
  const compact = (events: any[]) => {
13
- const dag = historyDagFromNodes(toEventNodes(events, mutations))
13
+ const dag = historyDagFromNodes(toEventNodes(events, mutations, 'client-id', 'session-id'))
14
14
  const compacted = compactEvents(dag)
15
15
 
16
16
  return Array.from(compacted.dag.nodeEntries())
@@ -50,8 +50,8 @@ describe('compactEvents calculator', () => {
50
50
 
51
51
  expect(expected).toMatchInlineSnapshot(`
52
52
  [
53
- { id: 0, parentId: -1, mutation: "add", args: { value: 1 }, facts: "" }
54
- { id: 1, parentId: 0, mutation: "add", args: { value: 1 }, facts: "" }
53
+ { id: 0, parentId: -1, mutation: "add", args: { value: 1 }, clientId: "client-id", sessionId: "session-id", facts: "" }
54
+ { id: 1, parentId: 0, mutation: "add", args: { value: 1 }, clientId: "client-id", sessionId: "session-id", facts: "" }
55
55
  ]
56
56
  `)
57
57
  })
@@ -64,8 +64,8 @@ describe('compactEvents calculator', () => {
64
64
 
65
65
  expect(expected).toMatchInlineSnapshot(`
66
66
  [
67
- { id: 0, parentId: -1, mutation: "multiply", args: { value: 2 }, facts: "?multiplyByZero -multiplyByZero" }
68
- { id: 1, parentId: 0, mutation: "multiply", args: { value: 2 }, facts: "?multiplyByZero -multiplyByZero" }
67
+ { id: 0, parentId: -1, mutation: "multiply", args: { value: 2 }, clientId: "client-id", sessionId: "session-id", facts: "?multiplyByZero -multiplyByZero" }
68
+ { id: 1, parentId: 0, mutation: "multiply", args: { value: 2 }, clientId: "client-id", sessionId: "session-id", facts: "?multiplyByZero -multiplyByZero" }
69
69
  ]
70
70
  `)
71
71
  })
@@ -79,7 +79,7 @@ describe('compactEvents calculator', () => {
79
79
 
80
80
  expect(expected).toMatchInlineSnapshot(`
81
81
  [
82
- { id: 2, parentId: -1, mutation: "multiply", args: { value: 0 }, facts: "+multiplyByZero" }
82
+ { id: 2, parentId: -1, mutation: "multiply", args: { value: 0 }, clientId: "client-id", sessionId: "session-id", facts: "+multiplyByZero" }
83
83
  ]
84
84
  `)
85
85
  })
@@ -94,8 +94,8 @@ describe('compactEvents calculator', () => {
94
94
 
95
95
  expect(expected).toMatchInlineSnapshot(`
96
96
  [
97
- { id: 2, parentId: -1, mutation: "multiply", args: { value: 0 }, facts: "+multiplyByZero" }
98
- { id: 3, parentId: 2, mutation: "add", args: { value: 1 }, facts: "" }
97
+ { id: 2, parentId: -1, mutation: "multiply", args: { value: 0 }, clientId: "client-id", sessionId: "session-id", facts: "+multiplyByZero" }
98
+ { id: 3, parentId: 2, mutation: "add", args: { value: 1 }, clientId: "client-id", sessionId: "session-id", facts: "" }
99
99
  ]
100
100
  `)
101
101
  })
@@ -111,10 +111,10 @@ describe('compactEvents calculator', () => {
111
111
 
112
112
  expect(expected).toMatchInlineSnapshot(`
113
113
  [
114
- { id: 0, parentId: -1, mutation: "add", args: { value: 1 }, facts: "" }
115
- { id: 2, parentId: 0, mutation: "multiply", args: { value: 0 }, facts: "+multiplyByZero" }
116
- { id: 3, parentId: 2, mutation: "multiply", args: { value: 2 }, facts: "?multiplyByZero +multiplyByZero -multiplyByZero" }
117
- { id: 4, parentId: 3, mutation: "add", args: { value: 1 }, facts: "" }
114
+ { id: 0, parentId: -1, mutation: "add", args: { value: 1 }, clientId: "client-id", sessionId: "session-id", facts: "" }
115
+ { id: 2, parentId: 0, mutation: "multiply", args: { value: 0 }, clientId: "client-id", sessionId: "session-id", facts: "+multiplyByZero" }
116
+ { id: 3, parentId: 2, mutation: "multiply", args: { value: 2 }, clientId: "client-id", sessionId: "session-id", facts: "?multiplyByZero +multiplyByZero -multiplyByZero" }
117
+ { id: 4, parentId: 3, mutation: "add", args: { value: 1 }, clientId: "client-id", sessionId: "session-id", facts: "" }
118
118
  ]
119
119
  `)
120
120
  })