@livestore/common 0.4.0-dev.22 → 0.4.0-dev.23

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 (313) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/ClientSessionLeaderThreadProxy.d.ts +9 -9
  3. package/dist/ClientSessionLeaderThreadProxy.d.ts.map +1 -1
  4. package/dist/WorkerTransportError.d.ts +11 -0
  5. package/dist/WorkerTransportError.d.ts.map +1 -0
  6. package/dist/WorkerTransportError.js +11 -0
  7. package/dist/WorkerTransportError.js.map +1 -0
  8. package/dist/adapter-types.d.ts +3 -3
  9. package/dist/adapter-types.d.ts.map +1 -1
  10. package/dist/adapter-types.js.map +1 -1
  11. package/dist/bounded-collections.d.ts.map +1 -1
  12. package/dist/bounded-collections.js +6 -4
  13. package/dist/bounded-collections.js.map +1 -1
  14. package/dist/debug-info.js +4 -4
  15. package/dist/debug-info.js.map +1 -1
  16. package/dist/devtools/devtools-messages-common.js +1 -1
  17. package/dist/devtools/devtools-messages-common.js.map +1 -1
  18. package/dist/devtools/mod.js +1 -1
  19. package/dist/devtools/mod.js.map +1 -1
  20. package/dist/errors.d.ts +15 -15
  21. package/dist/errors.d.ts.map +1 -1
  22. package/dist/errors.js +11 -11
  23. package/dist/errors.js.map +1 -1
  24. package/dist/index.d.ts +2 -0
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +2 -0
  27. package/dist/index.js.map +1 -1
  28. package/dist/leader-thread/LeaderSyncProcessor.d.ts +20 -6
  29. package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -1
  30. package/dist/leader-thread/LeaderSyncProcessor.js +287 -257
  31. package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -1
  32. package/dist/leader-thread/RejectedPushError.d.ts +107 -0
  33. package/dist/leader-thread/RejectedPushError.d.ts.map +1 -0
  34. package/dist/leader-thread/RejectedPushError.js +78 -0
  35. package/dist/leader-thread/RejectedPushError.js.map +1 -0
  36. package/dist/leader-thread/connection.js +1 -1
  37. package/dist/leader-thread/connection.js.map +1 -1
  38. package/dist/leader-thread/eventlog.d.ts.map +1 -1
  39. package/dist/leader-thread/eventlog.js +12 -11
  40. package/dist/leader-thread/eventlog.js.map +1 -1
  41. package/dist/leader-thread/leader-worker-devtools.d.ts +1 -2
  42. package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
  43. package/dist/leader-thread/leader-worker-devtools.js +25 -14
  44. package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
  45. package/dist/leader-thread/make-leader-thread-layer.d.ts +8 -3
  46. package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
  47. package/dist/leader-thread/make-leader-thread-layer.js +7 -10
  48. package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
  49. package/dist/leader-thread/make-leader-thread-layer.test.js +1 -1
  50. package/dist/leader-thread/make-leader-thread-layer.test.js.map +1 -1
  51. package/dist/leader-thread/materialize-event.js +4 -4
  52. package/dist/leader-thread/materialize-event.js.map +1 -1
  53. package/dist/leader-thread/recreate-db.js +1 -1
  54. package/dist/leader-thread/recreate-db.js.map +1 -1
  55. package/dist/leader-thread/shutdown-channel.d.ts +2 -2
  56. package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
  57. package/dist/leader-thread/shutdown-channel.js +2 -2
  58. package/dist/leader-thread/shutdown-channel.js.map +1 -1
  59. package/dist/leader-thread/stream-events.d.ts.map +1 -1
  60. package/dist/leader-thread/stream-events.js +4 -3
  61. package/dist/leader-thread/stream-events.js.map +1 -1
  62. package/dist/leader-thread/types.d.ts +7 -6
  63. package/dist/leader-thread/types.d.ts.map +1 -1
  64. package/dist/leader-thread/types.js.map +1 -1
  65. package/dist/logging.js +4 -4
  66. package/dist/logging.js.map +1 -1
  67. package/dist/make-client-session.js +2 -2
  68. package/dist/make-client-session.js.map +1 -1
  69. package/dist/materializer-helper.js +6 -6
  70. package/dist/materializer-helper.js.map +1 -1
  71. package/dist/otel.d.ts +1 -1
  72. package/dist/otel.d.ts.map +1 -1
  73. package/dist/otel.js +2 -2
  74. package/dist/otel.js.map +1 -1
  75. package/dist/rematerialize-from-eventlog.d.ts +1 -1
  76. package/dist/rematerialize-from-eventlog.d.ts.map +1 -1
  77. package/dist/rematerialize-from-eventlog.js +11 -9
  78. package/dist/rematerialize-from-eventlog.js.map +1 -1
  79. package/dist/schema/EventDef/define.d.ts +2 -2
  80. package/dist/schema/EventDef/define.d.ts.map +1 -1
  81. package/dist/schema/EventDef/define.js +4 -4
  82. package/dist/schema/EventDef/define.js.map +1 -1
  83. package/dist/schema/EventDef/deprecated.js +3 -3
  84. package/dist/schema/EventDef/deprecated.js.map +1 -1
  85. package/dist/schema/EventDef/deprecated.test.js +1 -1
  86. package/dist/schema/EventDef/deprecated.test.js.map +1 -1
  87. package/dist/schema/EventSequenceNumber/client.d.ts.map +1 -1
  88. package/dist/schema/EventSequenceNumber/client.js +11 -11
  89. package/dist/schema/EventSequenceNumber/client.js.map +1 -1
  90. package/dist/schema/EventSequenceNumber.test.js +1 -1
  91. package/dist/schema/EventSequenceNumber.test.js.map +1 -1
  92. package/dist/schema/LiveStoreEvent/client.d.ts.map +1 -1
  93. package/dist/schema/LiveStoreEvent/client.js +6 -3
  94. package/dist/schema/LiveStoreEvent/client.js.map +1 -1
  95. package/dist/schema/LiveStoreEvent/client.test.d.ts +2 -0
  96. package/dist/schema/LiveStoreEvent/client.test.d.ts.map +1 -0
  97. package/dist/schema/LiveStoreEvent/client.test.js +83 -0
  98. package/dist/schema/LiveStoreEvent/client.test.js.map +1 -0
  99. package/dist/schema/schema.d.ts.map +1 -1
  100. package/dist/schema/schema.js +7 -4
  101. package/dist/schema/schema.js.map +1 -1
  102. package/dist/schema/state/sqlite/client-document-def.d.ts.map +1 -1
  103. package/dist/schema/state/sqlite/client-document-def.js +18 -6
  104. package/dist/schema/state/sqlite/client-document-def.js.map +1 -1
  105. package/dist/schema/state/sqlite/client-document-def.test.js +1 -1
  106. package/dist/schema/state/sqlite/client-document-def.test.js.map +1 -1
  107. package/dist/schema/state/sqlite/column-annotations.d.ts.map +1 -1
  108. package/dist/schema/state/sqlite/column-annotations.js +1 -1
  109. package/dist/schema/state/sqlite/column-annotations.js.map +1 -1
  110. package/dist/schema/state/sqlite/column-annotations.test.js +1 -1
  111. package/dist/schema/state/sqlite/column-annotations.test.js.map +1 -1
  112. package/dist/schema/state/sqlite/column-def.d.ts.map +1 -1
  113. package/dist/schema/state/sqlite/column-def.js +36 -34
  114. package/dist/schema/state/sqlite/column-def.js.map +1 -1
  115. package/dist/schema/state/sqlite/column-def.test.js +7 -6
  116. package/dist/schema/state/sqlite/column-def.test.js.map +1 -1
  117. package/dist/schema/state/sqlite/column-spec.d.ts.map +1 -1
  118. package/dist/schema/state/sqlite/column-spec.js +8 -8
  119. package/dist/schema/state/sqlite/column-spec.js.map +1 -1
  120. package/dist/schema/state/sqlite/column-spec.test.js +1 -1
  121. package/dist/schema/state/sqlite/column-spec.test.js.map +1 -1
  122. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js +2 -2
  123. package/dist/schema/state/sqlite/db-schema/ast/sqlite.js.map +1 -1
  124. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts +2 -2
  125. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.d.ts.map +1 -1
  126. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js +11 -2
  127. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.js.map +1 -1
  128. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js +1 -1
  129. package/dist/schema/state/sqlite/db-schema/dsl/field-defs.test.js.map +1 -1
  130. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts +1 -1
  131. package/dist/schema/state/sqlite/db-schema/dsl/mod.d.ts.map +1 -1
  132. package/dist/schema/state/sqlite/db-schema/dsl/mod.js +1 -1
  133. package/dist/schema/state/sqlite/db-schema/dsl/mod.js.map +1 -1
  134. package/dist/schema/state/sqlite/mod.d.ts.map +1 -1
  135. package/dist/schema/state/sqlite/mod.js +3 -5
  136. package/dist/schema/state/sqlite/mod.js.map +1 -1
  137. package/dist/schema/state/sqlite/query-builder/api.d.ts +10 -2
  138. package/dist/schema/state/sqlite/query-builder/api.d.ts.map +1 -1
  139. package/dist/schema/state/sqlite/query-builder/astToSql.js +11 -11
  140. package/dist/schema/state/sqlite/query-builder/astToSql.js.map +1 -1
  141. package/dist/schema/state/sqlite/query-builder/impl.d.ts +1 -1
  142. package/dist/schema/state/sqlite/query-builder/impl.d.ts.map +1 -1
  143. package/dist/schema/state/sqlite/query-builder/impl.js +28 -14
  144. package/dist/schema/state/sqlite/query-builder/impl.js.map +1 -1
  145. package/dist/schema/state/sqlite/query-builder/impl.test.js +3 -2
  146. package/dist/schema/state/sqlite/query-builder/impl.test.js.map +1 -1
  147. package/dist/schema/state/sqlite/schema-helpers.js +2 -2
  148. package/dist/schema/state/sqlite/schema-helpers.js.map +1 -1
  149. package/dist/schema/state/sqlite/table-def.d.ts +5 -3
  150. package/dist/schema/state/sqlite/table-def.d.ts.map +1 -1
  151. package/dist/schema/state/sqlite/table-def.js +1 -1
  152. package/dist/schema/state/sqlite/table-def.js.map +1 -1
  153. package/dist/schema/state/sqlite/table-def.test.js +57 -4
  154. package/dist/schema/state/sqlite/table-def.test.js.map +1 -1
  155. package/dist/schema/unknown-events.d.ts +1 -1
  156. package/dist/schema/unknown-events.d.ts.map +1 -1
  157. package/dist/schema/unknown-events.js +1 -1
  158. package/dist/schema/unknown-events.js.map +1 -1
  159. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js +1 -1
  160. package/dist/schema-management/__tests__/migrations-autoincrement-quoting.test.js.map +1 -1
  161. package/dist/schema-management/common.js +2 -2
  162. package/dist/schema-management/common.js.map +1 -1
  163. package/dist/schema-management/migrations.js +1 -1
  164. package/dist/schema-management/migrations.js.map +1 -1
  165. package/dist/sql-queries/sql-queries.js +8 -6
  166. package/dist/sql-queries/sql-queries.js.map +1 -1
  167. package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
  168. package/dist/sql-queries/sql-query-builder.js.map +1 -1
  169. package/dist/sqlite-db-helper.js +3 -3
  170. package/dist/sqlite-db-helper.js.map +1 -1
  171. package/dist/sqlite-types.d.ts +2 -2
  172. package/dist/sqlite-types.d.ts.map +1 -1
  173. package/dist/sqlite-types.js.map +1 -1
  174. package/dist/sync/ClientSessionSyncProcessor.d.ts +8 -9
  175. package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -1
  176. package/dist/sync/ClientSessionSyncProcessor.js +95 -113
  177. package/dist/sync/ClientSessionSyncProcessor.js.map +1 -1
  178. package/dist/sync/errors.d.ts +0 -38
  179. package/dist/sync/errors.d.ts.map +1 -1
  180. package/dist/sync/errors.js +3 -20
  181. package/dist/sync/errors.js.map +1 -1
  182. package/dist/sync/mock-sync-backend.d.ts +5 -3
  183. package/dist/sync/mock-sync-backend.d.ts.map +1 -1
  184. package/dist/sync/mock-sync-backend.js +70 -68
  185. package/dist/sync/mock-sync-backend.js.map +1 -1
  186. package/dist/sync/next/compact-events.js +6 -6
  187. package/dist/sync/next/compact-events.js.map +1 -1
  188. package/dist/sync/next/facts.d.ts.map +1 -1
  189. package/dist/sync/next/facts.js +6 -6
  190. package/dist/sync/next/facts.js.map +1 -1
  191. package/dist/sync/next/history-dag-common.d.ts.map +1 -1
  192. package/dist/sync/next/history-dag-common.js +6 -6
  193. package/dist/sync/next/history-dag-common.js.map +1 -1
  194. package/dist/sync/next/history-dag.js +3 -3
  195. package/dist/sync/next/history-dag.js.map +1 -1
  196. package/dist/sync/next/rebase-events.js +1 -1
  197. package/dist/sync/next/rebase-events.js.map +1 -1
  198. package/dist/sync/next/test/compact-events.calculator.test.js +2 -2
  199. package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
  200. package/dist/sync/next/test/compact-events.test.d.ts.map +1 -1
  201. package/dist/sync/next/test/compact-events.test.js +2 -2
  202. package/dist/sync/next/test/compact-events.test.js.map +1 -1
  203. package/dist/sync/next/test/event-fixtures.d.ts.map +1 -1
  204. package/dist/sync/next/test/event-fixtures.js +2 -2
  205. package/dist/sync/next/test/event-fixtures.js.map +1 -1
  206. package/dist/sync/sync-backend-kv.d.ts.map +1 -1
  207. package/dist/sync/sync-backend-kv.js.map +1 -1
  208. package/dist/sync/sync-backend.d.ts +3 -3
  209. package/dist/sync/sync-backend.d.ts.map +1 -1
  210. package/dist/sync/sync-backend.js +1 -1
  211. package/dist/sync/sync-backend.js.map +1 -1
  212. package/dist/sync/sync.d.ts +20 -0
  213. package/dist/sync/sync.d.ts.map +1 -1
  214. package/dist/sync/syncstate.d.ts +4 -17
  215. package/dist/sync/syncstate.d.ts.map +1 -1
  216. package/dist/sync/syncstate.js +51 -74
  217. package/dist/sync/syncstate.js.map +1 -1
  218. package/dist/sync/syncstate.test.js +112 -96
  219. package/dist/sync/syncstate.test.js.map +1 -1
  220. package/dist/sync/transport-chunking.js +3 -3
  221. package/dist/sync/transport-chunking.js.map +1 -1
  222. package/dist/sync/validate-push-payload.d.ts +2 -2
  223. package/dist/sync/validate-push-payload.d.ts.map +1 -1
  224. package/dist/sync/validate-push-payload.js +4 -6
  225. package/dist/sync/validate-push-payload.js.map +1 -1
  226. package/dist/util.js +2 -2
  227. package/dist/util.js.map +1 -1
  228. package/dist/version.d.ts.map +1 -1
  229. package/dist/version.js +2 -5
  230. package/dist/version.js.map +1 -1
  231. package/package.json +66 -12
  232. package/src/ClientSessionLeaderThreadProxy.ts +9 -9
  233. package/src/WorkerTransportError.ts +12 -0
  234. package/src/adapter-types.ts +9 -3
  235. package/src/bounded-collections.ts +6 -5
  236. package/src/debug-info.ts +4 -4
  237. package/src/devtools/devtools-messages-common.ts +1 -1
  238. package/src/devtools/mod.ts +1 -1
  239. package/src/errors.ts +18 -17
  240. package/src/index.ts +2 -0
  241. package/src/leader-thread/LeaderSyncProcessor.ts +421 -392
  242. package/src/leader-thread/RejectedPushError.ts +106 -0
  243. package/src/leader-thread/connection.ts +1 -1
  244. package/src/leader-thread/eventlog.ts +16 -14
  245. package/src/leader-thread/leader-worker-devtools.ts +96 -66
  246. package/src/leader-thread/make-leader-thread-layer.test.ts +1 -1
  247. package/src/leader-thread/make-leader-thread-layer.ts +33 -31
  248. package/src/leader-thread/materialize-event.ts +4 -4
  249. package/src/leader-thread/recreate-db.ts +1 -1
  250. package/src/leader-thread/shutdown-channel.ts +2 -6
  251. package/src/leader-thread/stream-events.ts +10 -5
  252. package/src/leader-thread/types.ts +7 -6
  253. package/src/logging.ts +4 -4
  254. package/src/make-client-session.ts +2 -2
  255. package/src/materializer-helper.ts +9 -9
  256. package/src/otel.ts +3 -2
  257. package/src/rematerialize-from-eventlog.ts +60 -60
  258. package/src/schema/EventDef/define.ts +6 -6
  259. package/src/schema/EventDef/deprecated.test.ts +2 -1
  260. package/src/schema/EventDef/deprecated.ts +3 -3
  261. package/src/schema/EventSequenceNumber/client.ts +11 -11
  262. package/src/schema/EventSequenceNumber.test.ts +2 -1
  263. package/src/schema/LiveStoreEvent/client.test.ts +97 -0
  264. package/src/schema/LiveStoreEvent/client.ts +6 -3
  265. package/src/schema/schema.ts +9 -4
  266. package/src/schema/state/sqlite/client-document-def.test.ts +2 -1
  267. package/src/schema/state/sqlite/client-document-def.ts +20 -6
  268. package/src/schema/state/sqlite/column-annotations.test.ts +2 -1
  269. package/src/schema/state/sqlite/column-annotations.ts +2 -1
  270. package/src/schema/state/sqlite/column-def.test.ts +8 -6
  271. package/src/schema/state/sqlite/column-def.ts +41 -36
  272. package/src/schema/state/sqlite/column-spec.test.ts +3 -1
  273. package/src/schema/state/sqlite/column-spec.ts +9 -8
  274. package/src/schema/state/sqlite/db-schema/ast/sqlite.ts +2 -2
  275. package/src/schema/state/sqlite/db-schema/dsl/field-defs.test.ts +2 -1
  276. package/src/schema/state/sqlite/db-schema/dsl/field-defs.ts +13 -4
  277. package/src/schema/state/sqlite/db-schema/dsl/mod.ts +3 -3
  278. package/src/schema/state/sqlite/mod.ts +4 -5
  279. package/src/schema/state/sqlite/query-builder/api.ts +12 -5
  280. package/src/schema/state/sqlite/query-builder/astToSql.ts +11 -11
  281. package/src/schema/state/sqlite/query-builder/impl.test.ts +4 -2
  282. package/src/schema/state/sqlite/query-builder/impl.ts +26 -12
  283. package/src/schema/state/sqlite/schema-helpers.ts +2 -2
  284. package/src/schema/state/sqlite/table-def.test.ts +67 -4
  285. package/src/schema/state/sqlite/table-def.ts +8 -15
  286. package/src/schema/unknown-events.ts +2 -2
  287. package/src/schema-management/__tests__/migrations-autoincrement-quoting.test.ts +3 -1
  288. package/src/schema-management/common.ts +2 -2
  289. package/src/schema-management/migrations.ts +1 -1
  290. package/src/sql-queries/sql-queries.ts +10 -6
  291. package/src/sql-queries/sql-query-builder.ts +1 -0
  292. package/src/sqlite-db-helper.ts +3 -3
  293. package/src/sqlite-types.ts +3 -2
  294. package/src/sync/ClientSessionSyncProcessor.ts +148 -152
  295. package/src/sync/errors.ts +10 -22
  296. package/src/sync/mock-sync-backend.ts +139 -97
  297. package/src/sync/next/compact-events.ts +5 -5
  298. package/src/sync/next/facts.ts +7 -6
  299. package/src/sync/next/history-dag-common.ts +9 -6
  300. package/src/sync/next/history-dag.ts +3 -3
  301. package/src/sync/next/rebase-events.ts +1 -1
  302. package/src/sync/next/test/compact-events.calculator.test.ts +3 -2
  303. package/src/sync/next/test/compact-events.test.ts +4 -3
  304. package/src/sync/next/test/event-fixtures.ts +2 -2
  305. package/src/sync/sync-backend-kv.ts +1 -0
  306. package/src/sync/sync-backend.ts +5 -4
  307. package/src/sync/sync.ts +21 -0
  308. package/src/sync/syncstate.test.ts +513 -435
  309. package/src/sync/syncstate.ts +80 -86
  310. package/src/sync/transport-chunking.ts +3 -3
  311. package/src/sync/validate-push-payload.ts +4 -6
  312. package/src/util.ts +2 -2
  313. package/src/version.ts +2 -6
@@ -23,7 +23,7 @@ export const findManyRows = <TColumns extends SqliteDsl.Columns>({
23
23
  }): [string, BindValues] => {
24
24
  const whereSql = buildWhereSql({ where })
25
25
  const whereModifier = whereSql === '' ? '' : `WHERE ${whereSql}`
26
- const limitModifier = limit ? `LIMIT ${limit}` : ''
26
+ const limitModifier = limit !== undefined ? `LIMIT ${limit}` : ''
27
27
 
28
28
  const whereBindValues = makeBindValues({ columns, values: where, variablePrefix: 'where_', skipNil: true })
29
29
 
@@ -80,7 +80,7 @@ export const insertRowPrepared = <TColumns extends SqliteDsl.Columns>({
80
80
  const keysStr = keys.join(', ')
81
81
  const valuesStr = keys.map((key) => `$${key}`).join(', ')
82
82
 
83
- return sql`INSERT ${options.orReplace ? 'OR REPLACE ' : ''}INTO ${tableName} (${keysStr}) VALUES (${valuesStr})`
83
+ return sql`INSERT ${options.orReplace === true ? 'OR REPLACE ' : ''}INTO ${tableName} (${keysStr}) VALUES (${valuesStr})`
84
84
  }
85
85
 
86
86
  export const insertRows = <TColumns extends SqliteDsl.Columns>({
@@ -134,7 +134,7 @@ export const insertOrIgnoreRow = <TColumns extends SqliteDsl.Columns>({
134
134
  .join(', ')
135
135
 
136
136
  const bindValues = makeBindValues({ columns, values })
137
- const returningStmt = returnRow ? 'RETURNING *' : ''
137
+ const returningStmt = returnRow === true ? 'RETURNING *' : ''
138
138
 
139
139
  return [sql`INSERT OR IGNORE INTO ${tableName} (${keysStr}) VALUES (${valuesStr}) ${returningStmt}`, bindValues]
140
140
  }
@@ -251,7 +251,7 @@ export const createTable = ({
251
251
  if (columnDef.default._tag === 'None') return ''
252
252
  const defaultValue = columnDef.default.value
253
253
  if (typeof defaultValue === 'function') return ''
254
- if (defaultValue && typeof defaultValue === 'object' && 'sql' in defaultValue) {
254
+ if (defaultValue !== undefined && typeof defaultValue === 'object' && 'sql' in defaultValue) {
255
255
  return `DEFAULT ${defaultValue.sql}`
256
256
  }
257
257
  return `DEFAULT ${defaultValue}`
@@ -301,7 +301,7 @@ Error: ${parseErrorStr}
301
301
  Value:`,
302
302
  value,
303
303
  )
304
- // biome-ignore lint/suspicious/noDebugger: debug
304
+ // oxlint-disable-next-line eslint(no-debugger) -- intentional breakpoint for SQL decode errors
305
305
  debugger
306
306
  throw res.left
307
307
  } else {
@@ -349,7 +349,11 @@ const buildWhereSql = <TColumns extends SqliteDsl.Columns>({
349
349
  const getWhereOp = (columnName: string, value: ClientTypes.WhereValueForDecoded<any>) => {
350
350
  if (value === null) {
351
351
  return `IS NULL`
352
- } else if (typeof value === 'object' && typeof value.op === 'string' && ClientTypes.isValidWhereOp(value.op)) {
352
+ } else if (
353
+ typeof value === 'object' &&
354
+ typeof value.op === 'string' &&
355
+ ClientTypes.isValidWhereOp(value.op) === true
356
+ ) {
353
357
  return `${value.op} $where_${columnName}`
354
358
  } else if (typeof value === 'object' && typeof value.op === 'string' && value.op === 'in') {
355
359
  return `in (${value.val.map((_: any, i: number) => `$where_${columnName}_${i}`).join(', ')})`
@@ -1,4 +1,5 @@
1
1
  import { omitUndefineds } from '@livestore/utils'
2
+
2
3
  import type { SqliteDsl } from '../schema/state/sqlite/db-schema/mod.ts'
3
4
  import type { BindValues } from './sql-queries.ts'
4
5
  import * as SqlQueries from './sql-queries.ts'
@@ -14,7 +14,7 @@ export const makeExecute = (
14
14
  return (...args: any[]) => {
15
15
  const [queryStrOrQueryBuilder, bindValuesOrOptions, maybeOptions] = args
16
16
 
17
- if (isQueryBuilder(queryStrOrQueryBuilder)) {
17
+ if (isQueryBuilder(queryStrOrQueryBuilder) === true) {
18
18
  const { query, bindValues } = queryStrOrQueryBuilder.asSql()
19
19
  return execute(query, bindValues as unknown as PreparedBindValues, bindValuesOrOptions)
20
20
  } else {
@@ -29,7 +29,7 @@ export const makeSelect = <T>(
29
29
  return (...args: any[]) => {
30
30
  const [queryStrOrQueryBuilder, maybeBindValues] = args
31
31
 
32
- if (isQueryBuilder(queryStrOrQueryBuilder)) {
32
+ if (isQueryBuilder(queryStrOrQueryBuilder) === true) {
33
33
  const { query, bindValues } = queryStrOrQueryBuilder.asSql()
34
34
  const resultSchema = getResultSchema(queryStrOrQueryBuilder)
35
35
  const results = select(query, bindValues as unknown as PreparedBindValues)
@@ -44,7 +44,7 @@ export const validateSnapshot = (snapshot: Uint8Array) => {
44
44
  const headerBytes = new TextDecoder().decode(snapshot.slice(0, 16))
45
45
  const hasValidHeader = headerBytes.startsWith('SQLite format 3')
46
46
 
47
- if (!hasValidHeader) {
47
+ if (hasValidHeader === false) {
48
48
  throw new SqliteError({
49
49
  cause: 'Invalid SQLite header',
50
50
  note: `Expected header to start with 'SQLite format 3', but got: ${headerBytes}`,
@@ -1,4 +1,5 @@
1
1
  import { type Effect, Schema } from '@livestore/utils/effect'
2
+
2
3
  import type { SqliteError, UnknownError } from './errors.ts'
3
4
  import type { EventSequenceNumber } from './schema/mod.ts'
4
5
  import type { QueryBuilder } from './schema/state/sqlite/query-builder/api.ts'
@@ -17,12 +18,12 @@ export interface SqliteDb<TReq = any, TMetadata extends TReq = TReq> {
17
18
  prepare(queryStr: string): PreparedStatement
18
19
  execute(
19
20
  queryStr: string,
20
- bindValues?: PreparedBindValues | undefined,
21
+ bindValues?: PreparedBindValues ,
21
22
  options?: { onRowsChanged?: (rowsChanged: number) => void },
22
23
  ): void
23
24
  execute(queryBuilder: QueryBuilder.Any, options?: { onRowsChanged?: (rowsChanged: number) => void }): void
24
25
 
25
- select<T>(queryStr: string, bindValues?: PreparedBindValues | undefined): ReadonlyArray<T>
26
+ select<T>(queryStr: string, bindValues?: PreparedBindValues ): ReadonlyArray<T>
26
27
  select<T>(queryBuilder: QueryBuilder<T, any, any>): T
27
28
 
28
29
  export(): Uint8Array<ArrayBuffer>
@@ -1,5 +1,5 @@
1
1
  /// <reference lib="dom" />
2
- import { LS_DEV, shouldNeverHappen, TRACE_VERBOSE } from '@livestore/utils'
2
+ import { LS_DEV, TRACE_VERBOSE } from '@livestore/utils'
3
3
  import {
4
4
  BucketQueue,
5
5
  Effect,
@@ -7,25 +7,22 @@ import {
7
7
  FiberHandle,
8
8
  Option,
9
9
  Queue,
10
- type Runtime,
11
10
  Schema,
12
11
  type Scope,
13
12
  Stream,
14
13
  Subscribable,
15
14
  } from '@livestore/utils/effect'
16
- import type * as otel from '@opentelemetry/api'
17
15
 
18
- import { type ClientSession, UnknownError } from '../adapter-types.ts'
16
+ import type { ClientSession } from '../adapter-types.ts'
19
17
  import type { MaterializeError } from '../errors.ts'
18
+ import { isRejectedPushError } from '../leader-thread/RejectedPushError.ts'
20
19
  import * as EventSequenceNumber from '../schema/EventSequenceNumber/mod.ts'
21
20
  import * as LiveStoreEvent from '../schema/LiveStoreEvent/mod.ts'
22
21
  import type { LiveStoreSchema } from '../schema/mod.ts'
23
22
  import * as SyncState from './syncstate.ts'
24
23
 
25
- // WORKAROUND: @effect/opentelemetry mis-parses `Span.addEvent(name, attributes)` and treats the attributes object as a
26
- // time input, causing `TypeError: {} is not iterable` at runtime.
27
- // Upstream: https://github.com/Effect-TS/effect/pull/5929
28
- // TODO: simplify back to the 2-arg overload once the upstream fix is released and adopted.
24
+ /** Serialize value to JSON string for trace attributes */
25
+ const jsonStringify = Schema.encodeSync(Schema.parseJson())
29
26
 
30
27
  /**
31
28
  * Rebase behaviour:
@@ -42,20 +39,17 @@ import * as SyncState from './syncstate.ts'
42
39
  * - The leader sync processor pulls regular LiveStore events, while the session sync processor pulls SyncState.PayloadUpstream items
43
40
  * - The session sync processor has no downstream nodes.
44
41
  */
45
- export const makeClientSessionSyncProcessor = ({
42
+ export const makeClientSessionSyncProcessor = Effect.fn('makeClientSessionSyncProcessor')(function* ({
46
43
  schema,
47
44
  clientSession,
48
- runtime,
49
45
  materializeEvent,
50
46
  rollback,
51
47
  refreshTables,
52
- span,
53
48
  params,
54
49
  confirmUnsavedChanges,
55
50
  }: {
56
51
  schema: LiveStoreSchema
57
52
  clientSession: ClientSession
58
- runtime: Runtime.Runtime<Scope.Scope>
59
53
  materializeEvent: (
60
54
  eventEncoded: LiveStoreEvent.Client.EncodedWithMeta,
61
55
  options: { withChangeset: boolean; materializerHashLeader: Option.Option<number> },
@@ -72,7 +66,6 @@ export const makeClientSessionSyncProcessor = ({
72
66
  >
73
67
  rollback: (changeset: Uint8Array<ArrayBuffer>) => void
74
68
  refreshTables: (tables: Set<string>) => void
75
- span: otel.Span
76
69
  params: {
77
70
  leaderPushBatchSize: number
78
71
  simulation?: ClientSessionSyncProcessorSimulationParams
@@ -82,7 +75,7 @@ export const makeClientSessionSyncProcessor = ({
82
75
  * If true, registers a beforeunload event listener to confirm unsaved changes.
83
76
  */
84
77
  confirmUnsavedChanges: boolean
85
- }): ClientSessionSyncProcessor => {
78
+ }): Effect.fn.Return<ClientSessionSyncProcessor> {
86
79
  const eventSchema = LiveStoreEvent.Client.makeSchemaMemo(schema)
87
80
 
88
81
  const simSleep = <TKey extends keyof ClientSessionSyncProcessorSimulationParams>(
@@ -101,100 +94,19 @@ export const makeClientSessionSyncProcessor = ({
101
94
  }
102
95
 
103
96
  /** Only used for debugging / observability / testing, it's not relied upon for correctness of the sync processor. */
104
- const syncStateUpdateQueue = Queue.unbounded<SyncState.SyncState>().pipe(Effect.runSync)
97
+ const syncStateUpdateQueue = yield* Queue.unbounded<SyncState.SyncState>()
105
98
  const isClientEvent = (eventEncoded: LiveStoreEvent.Client.EncodedWithMeta) =>
106
99
  schema.eventsDefsMap.get(eventEncoded.name)?.options.clientOnly ?? false
107
100
 
108
101
  /** We're queuing push requests to reduce the number of messages sent to the leader by batching them */
109
- const leaderPushQueue = BucketQueue.make<LiveStoreEvent.Client.EncodedWithMeta>().pipe(Effect.runSync)
110
-
111
- const push: ClientSessionSyncProcessor['push'] = Effect.fn('client-session-sync-processor:push')(function* (batch) {
112
- // TODO validate batch
113
-
114
- let baseEventSequenceNumber = syncStateRef.current.localHead
115
- const encodedEventDefs = batch.map(({ name, args }) => {
116
- const eventDef = schema.eventsDefsMap.get(name)
117
- if (eventDef === undefined) {
118
- return shouldNeverHappen(`No event definition found for \`${name}\`.`)
119
- }
120
- const nextNumPair = EventSequenceNumber.Client.nextPair({
121
- seqNum: baseEventSequenceNumber,
122
- isClient: eventDef.options.clientOnly,
123
- rebaseGeneration: baseEventSequenceNumber.rebaseGeneration,
124
- })
125
- baseEventSequenceNumber = nextNumPair.seqNum
126
- return new LiveStoreEvent.Client.EncodedWithMeta(
127
- Schema.encodeUnknownSync(eventSchema)({
128
- name,
129
- args,
130
- ...nextNumPair,
131
- clientId: clientSession.clientId,
132
- sessionId: clientSession.sessionId,
133
- }),
134
- )
135
- })
136
-
137
- const mergeResult = SyncState.merge({
138
- syncState: syncStateRef.current,
139
- payload: { _tag: 'local-push', newEvents: encodedEventDefs },
140
- isClientEvent,
141
- isEqualEvent: LiveStoreEvent.Client.isEqualEncoded,
142
- })
143
-
144
- yield* Effect.annotateCurrentSpan({
145
- batchSize: encodedEventDefs.length,
146
- mergeResultTag: mergeResult._tag,
147
- eventCounts: encodedEventDefs.reduce<Record<string, number>>((acc, event) => {
148
- acc[event.name] = (acc[event.name] ?? 0) + 1
149
- return acc
150
- }, {}),
151
- ...(TRACE_VERBOSE && { mergeResult: JSON.stringify(mergeResult) }),
152
- })
153
-
154
- if (mergeResult._tag === 'unknown-error') {
155
- return shouldNeverHappen('Unknown error in client-session-sync-processor', mergeResult.message)
156
- }
157
-
158
- if (mergeResult._tag !== 'advance') {
159
- return shouldNeverHappen(`Expected advance, got ${mergeResult._tag}`)
160
- }
161
-
162
- syncStateRef.current = mergeResult.newSyncState
163
- yield* syncStateUpdateQueue.offer(mergeResult.newSyncState)
164
-
165
- // Materialize events to state
166
- const writeTables = new Set<string>()
167
- for (const event of mergeResult.newEvents) {
168
- const {
169
- writeTables: newWriteTables,
170
- sessionChangeset,
171
- materializerHash,
172
- } = yield* materializeEvent(event, {
173
- withChangeset: true,
174
- materializerHashLeader: Option.none(),
175
- })
176
- for (const table of newWriteTables) {
177
- writeTables.add(table)
178
- }
179
- event.meta.sessionChangeset = sessionChangeset
180
- event.meta.materializerHashSession = materializerHash
181
- }
182
-
183
- // Trigger push to leader
184
- // console.debug('pushToLeader', encodedEventDefs.length, ...encodedEventDefs.map((_) => _.toJSON()))
185
- yield* BucketQueue.offerAll(leaderPushQueue, encodedEventDefs)
186
-
187
- return { writeTables }
188
- })
189
-
190
- const debugInfo = {
191
- rebaseCount: 0,
192
- advanceCount: 0,
193
- rejectCount: 0,
194
- }
195
-
196
- const boot: ClientSessionSyncProcessor['boot'] = Effect.gen(function* () {
197
- if (confirmUnsavedChanges && typeof window !== 'undefined' && typeof window.addEventListener === 'function') {
102
+ const leaderPushQueue = yield* BucketQueue.make<LiveStoreEvent.Client.EncodedWithMeta>()
103
+
104
+ const boot: ClientSessionSyncProcessor['boot'] = Effect.fn('client-session-sync-processor:boot')(function* () {
105
+ if (
106
+ confirmUnsavedChanges === true &&
107
+ typeof window !== 'undefined' &&
108
+ typeof window.addEventListener === 'function'
109
+ ) {
198
110
  const onBeforeUnload = (event: BeforeUnloadEvent) => {
199
111
  if (syncStateRef.current.pending.length > 0) {
200
112
  // Trigger the default browser dialog
@@ -213,12 +125,17 @@ export const makeClientSessionSyncProcessor = ({
213
125
  const backgroundLeaderPushing = Effect.gen(function* () {
214
126
  const batch = yield* BucketQueue.takeBetween(leaderPushQueue, 1, params.leaderPushBatchSize)
215
127
  yield* clientSession.leaderThread.events.push(batch).pipe(
216
- Effect.catchTag('LeaderAheadError', () => {
128
+ Effect.catchIf(isRejectedPushError, () => {
217
129
  debugInfo.rejectCount++
218
130
  return BucketQueue.clear(leaderPushQueue)
219
131
  }),
220
132
  )
221
- }).pipe(Effect.forever, Effect.interruptible, Effect.tapCauseLogPretty)
133
+ }).pipe(
134
+ Effect.forever,
135
+ Effect.interruptible,
136
+ Effect.tapCauseLogPretty,
137
+ Effect.catchAllCause((cause) => clientSession.shutdown(Exit.failCause(cause))),
138
+ )
222
139
 
223
140
  yield* FiberHandle.run(leaderPushingFiberHandle, backgroundLeaderPushing)
224
141
 
@@ -230,52 +147,47 @@ export const makeClientSessionSyncProcessor = ({
230
147
  Effect.gen(function* () {
231
148
  // yield* Effect.logDebug('ClientSessionSyncProcessor:pull', payload)
232
149
 
233
- if (clientSession.devtools.enabled) {
150
+ if (clientSession.devtools.enabled === true) {
234
151
  yield* clientSession.devtools.pullLatch.await
235
152
  }
236
153
 
237
- const mergeResult = SyncState.merge({
154
+ const mergeResult = yield* SyncState.merge({
238
155
  syncState: syncStateRef.current,
239
156
  payload,
240
157
  isClientEvent,
241
158
  isEqualEvent: LiveStoreEvent.Client.isEqualEncoded,
242
- })
243
-
244
- if (mergeResult._tag === 'unknown-error') {
245
- return yield* new UnknownError({ cause: mergeResult.message })
246
- } else if (mergeResult._tag === 'reject') {
247
- return shouldNeverHappen('Unexpected reject in client-session-sync-processor', mergeResult)
248
- }
159
+ }).pipe(
160
+ Effect.filterOrDieMessage(
161
+ (r) => r._tag !== 'reject',
162
+ 'Unexpected reject in client-session-sync-processor',
163
+ ),
164
+ )
249
165
 
250
166
  syncStateRef.current = mergeResult.newSyncState
251
167
 
252
168
  if (mergeResult._tag === 'rebase') {
253
- span.addEvent(
254
- 'merge:pull:rebase',
255
- {
256
- payloadTag: payload._tag,
257
- payload: TRACE_VERBOSE ? JSON.stringify(payload) : undefined,
258
- newEventsCount: mergeResult.newEvents.length,
259
- rollbackCount: mergeResult.rollbackEvents.length,
260
- res: TRACE_VERBOSE ? JSON.stringify(mergeResult) : undefined,
261
- },
262
- undefined,
263
- )
169
+ yield* Effect.spanEvent('merge:pull:rebase', {
170
+ payloadTag: payload._tag,
171
+ ...(TRACE_VERBOSE === true ? { payload: jsonStringify(payload) } : {}),
172
+ newEventsCount: mergeResult.newEvents.length,
173
+ rollbackCount: mergeResult.rollbackEvents.length,
174
+ ...(TRACE_VERBOSE === true ? { res: jsonStringify(mergeResult) } : {}),
175
+ })
264
176
 
265
177
  debugInfo.rebaseCount++
266
178
 
267
- if (SIMULATION_ENABLED) yield* simSleep('pull', '1_before_leader_push_fiber_interrupt')
179
+ if (SIMULATION_ENABLED === true) yield* simSleep('pull', '1_before_leader_push_fiber_interrupt')
268
180
 
269
181
  yield* FiberHandle.clear(leaderPushingFiberHandle)
270
182
 
271
- if (SIMULATION_ENABLED) yield* simSleep('pull', '2_before_leader_push_queue_clear')
183
+ if (SIMULATION_ENABLED === true) yield* simSleep('pull', '2_before_leader_push_queue_clear')
272
184
 
273
185
  // Reset the leader push queue since we're rebasing and will push again
274
186
  yield* BucketQueue.clear(leaderPushQueue)
275
187
 
276
- if (SIMULATION_ENABLED) yield* simSleep('pull', '3_before_rebase_rollback')
188
+ if (SIMULATION_ENABLED === true) yield* simSleep('pull', '3_before_rebase_rollback')
277
189
 
278
- if (LS_DEV) {
190
+ if (LS_DEV === true) {
279
191
  yield* Effect.logDebug(
280
192
  'merge:pull:rebase: rollback',
281
193
  mergeResult.rollbackEvents.length,
@@ -291,24 +203,20 @@ export const makeClientSessionSyncProcessor = ({
291
203
  }
292
204
  }
293
205
 
294
- if (SIMULATION_ENABLED) yield* simSleep('pull', '4_before_leader_push_queue_offer')
206
+ if (SIMULATION_ENABLED === true) yield* simSleep('pull', '4_before_leader_push_queue_offer')
295
207
 
296
208
  yield* BucketQueue.offerAll(leaderPushQueue, mergeResult.newSyncState.pending)
297
209
 
298
- if (SIMULATION_ENABLED) yield* simSleep('pull', '5_before_leader_push_fiber_run')
210
+ if (SIMULATION_ENABLED === true) yield* simSleep('pull', '5_before_leader_push_fiber_run')
299
211
 
300
212
  yield* FiberHandle.run(leaderPushingFiberHandle, backgroundLeaderPushing)
301
213
  } else {
302
- span.addEvent(
303
- 'merge:pull:advance',
304
- {
305
- payloadTag: payload._tag,
306
- payload: TRACE_VERBOSE ? JSON.stringify(payload) : undefined,
307
- newEventsCount: mergeResult.newEvents.length,
308
- res: TRACE_VERBOSE ? JSON.stringify(mergeResult) : undefined,
309
- },
310
- undefined,
311
- )
214
+ yield* Effect.spanEvent('merge:pull:advance', {
215
+ payloadTag: payload._tag,
216
+ ...(TRACE_VERBOSE === true ? { payload: jsonStringify(payload) } : {}),
217
+ newEventsCount: mergeResult.newEvents.length,
218
+ ...(TRACE_VERBOSE === true ? { res: jsonStringify(mergeResult) } : {}),
219
+ })
312
220
 
313
221
  debugInfo.advanceCount++
314
222
  }
@@ -353,17 +261,99 @@ export const makeClientSessionSyncProcessor = ({
353
261
  Effect.tapCauseLogPretty,
354
262
  Effect.forkScoped,
355
263
  )
264
+ })()
265
+
266
+ const encodeEvents: ClientSessionSyncProcessor['encodeEvents'] = Effect.fn('client-session-sync-processor:encode-events')(function* (
267
+ events,
268
+ ) {
269
+ let baseEventSequenceNumber = syncStateRef.current.localHead
270
+ return yield* Effect.forEach(events, ({ name, args }) =>
271
+ Effect.gen(function* () {
272
+ const eventDef = yield* Effect.fromNullable(schema.eventsDefsMap.get(name)).pipe(Effect.orDieDebugger)
273
+ const nextNumPair = EventSequenceNumber.Client.nextPair({
274
+ seqNum: baseEventSequenceNumber,
275
+ isClient: eventDef.options.clientOnly,
276
+ rebaseGeneration: baseEventSequenceNumber.rebaseGeneration,
277
+ })
278
+ baseEventSequenceNumber = nextNumPair.seqNum
279
+ return new LiveStoreEvent.Client.EncodedWithMeta(
280
+ Schema.encodeUnknownSync(eventSchema)({
281
+ name,
282
+ args,
283
+ ...nextNumPair,
284
+ clientId: clientSession.clientId,
285
+ sessionId: clientSession.sessionId,
286
+ }),
287
+ )
288
+ }),
289
+ )
290
+ })
291
+
292
+ const materializeEvents: ClientSessionSyncProcessor['materializeEvents'] = Effect.fn('client-session-sync-processor:materialize-events')(function* (
293
+ events,
294
+ ) {
295
+ const writeTables = new Set<string>()
296
+ for (const event of events) {
297
+ const {
298
+ writeTables: newWriteTables,
299
+ sessionChangeset,
300
+ materializerHash,
301
+ } = yield* materializeEvent(event, {
302
+ withChangeset: true,
303
+ materializerHashLeader: Option.none(),
304
+ })
305
+ for (const table of newWriteTables) {
306
+ writeTables.add(table)
307
+ }
308
+ event.meta.sessionChangeset = sessionChangeset
309
+ event.meta.materializerHashSession = materializerHash
310
+ }
311
+ return { writeTables }
312
+ })
313
+
314
+ const push: ClientSessionSyncProcessor['push'] = Effect.fn('client-session-sync-processor:push')(function* (
315
+ encodedEvents,
316
+ ) {
317
+ const mergeResult = yield* SyncState.merge({
318
+ syncState: syncStateRef.current,
319
+ payload: { _tag: 'local-push', newEvents: encodedEvents },
320
+ isClientEvent,
321
+ isEqualEvent: LiveStoreEvent.Client.isEqualEncoded,
322
+ }).pipe(
323
+ Effect.filterOrDieMessage(
324
+ (r) => r._tag === 'advance',
325
+ 'Expected advance from local-push merge',
326
+ ),
327
+ )
328
+
329
+ yield* Effect.annotateCurrentSpan({
330
+ batchSize: encodedEvents.length,
331
+ mergeResultTag: mergeResult._tag,
332
+ eventCounts: encodedEvents.reduce<Record<string, number>>((acc, event) => {
333
+ acc[event.name] = (acc[event.name] ?? 0) + 1
334
+ return acc
335
+ }, {}),
336
+ ...(TRACE_VERBOSE === true ? { mergeResult: jsonStringify(mergeResult) } : {}),
337
+ })
338
+
339
+ syncStateRef.current = mergeResult.newSyncState
340
+ yield* syncStateUpdateQueue.offer(mergeResult.newSyncState)
341
+ yield* BucketQueue.offerAll(leaderPushQueue, mergeResult.newEvents)
356
342
  })
357
343
 
344
+ const debugInfo = {
345
+ rebaseCount: 0,
346
+ advanceCount: 0,
347
+ rejectCount: 0,
348
+ }
349
+
358
350
  return {
359
- push,
360
351
  boot,
352
+ encodeEvents,
353
+ materializeEvents,
354
+ push,
361
355
  syncState: Subscribable.make({
362
- get: Effect.gen(function* () {
363
- const syncState = syncStateRef.current
364
- if (syncStateRef === undefined) return shouldNeverHappen('Not initialized')
365
- return syncState
366
- }),
356
+ get: Effect.sync(() => syncStateRef.current),
367
357
  changes: Stream.fromQueue(syncStateUpdateQueue),
368
358
  }),
369
359
  debug: {
@@ -378,17 +368,23 @@ export const makeClientSessionSyncProcessor = ({
378
368
  'pushQueueItems',
379
369
  pushQueueItems.map((_) => _.toJSON()),
380
370
  )
381
- }).pipe(Effect.provide(runtime), Effect.runSync),
371
+ }).pipe(Effect.runSync),
382
372
  debugInfo: () => debugInfo,
383
373
  },
384
374
  } satisfies ClientSessionSyncProcessor
385
- }
375
+ })
386
376
 
387
377
  export interface ClientSessionSyncProcessor {
378
+ boot: Effect.Effect<void, never, Scope.Scope>
379
+ encodeEvents: (
380
+ events: ReadonlyArray<LiveStoreEvent.Input.Decoded>,
381
+ ) => Effect.Effect<ReadonlyArray<LiveStoreEvent.Client.EncodedWithMeta>>
388
382
  push: (
389
- batch: ReadonlyArray<LiveStoreEvent.Input.Decoded>,
383
+ events: ReadonlyArray<LiveStoreEvent.Client.EncodedWithMeta>,
384
+ ) => Effect.Effect<void>
385
+ materializeEvents: (
386
+ events: ReadonlyArray<LiveStoreEvent.Client.EncodedWithMeta>,
390
387
  ) => Effect.Effect<{ writeTables: Set<string> }, MaterializeError>
391
- boot: Effect.Effect<void, UnknownError, Scope.Scope>
392
388
  /**
393
389
  * Only used for debugging / observability.
394
390
  */
@@ -1,38 +1,26 @@
1
1
  import { Schema } from '@livestore/utils/effect'
2
- import { UnknownError } from '../errors.ts'
2
+
3
3
  import { EventSequenceNumber } from '../schema/mod.ts'
4
4
 
5
- export class IsOfflineError extends Schema.TaggedError<IsOfflineError>()('IsOfflineError', {
5
+ export class IsOfflineError extends Schema.TaggedError<IsOfflineError>(
6
+ '~@livestore/common/IsOfflineError',
7
+ )('IsOfflineError', {
6
8
  cause: Schema.Defect,
7
9
  }) {}
8
10
 
9
11
  /** Unique ID generated by the backend when its created. Used to check whether the backend identity has changed. */
10
12
  export const BackendId = Schema.String.annotations({ title: '@livestore/sync-cf:BackendId' })
11
13
 
12
- export class BackendIdMismatchError extends Schema.TaggedError<BackendIdMismatchError>()('BackendIdMismatchError', {
14
+ export class BackendIdMismatchError extends Schema.TaggedError<BackendIdMismatchError>(
15
+ '~@livestore/common/BackendIdMismatchError',
16
+ )('BackendIdMismatchError', {
13
17
  expected: BackendId,
14
18
  received: BackendId,
15
19
  }) {}
16
20
 
17
- export class ServerAheadError extends Schema.TaggedError<ServerAheadError>()('ServerAheadError', {
21
+ export class ServerAheadError extends Schema.TaggedError<ServerAheadError>(
22
+ '~@livestore/common/ServerAheadError',
23
+ )('ServerAheadError', {
18
24
  minimumExpectedNum: EventSequenceNumber.Global.Schema,
19
25
  providedNum: EventSequenceNumber.Global.Schema,
20
26
  }) {}
21
-
22
- export class InvalidPushError extends Schema.TaggedError<InvalidPushError>()('InvalidPushError', {
23
- cause: Schema.Union(UnknownError, ServerAheadError, BackendIdMismatchError),
24
- }) {}
25
-
26
- export class InvalidPullError extends Schema.TaggedError<InvalidPullError>()('InvalidPullError', {
27
- cause: Schema.Defect,
28
- }) {}
29
-
30
- export class LeaderAheadError extends Schema.TaggedError<LeaderAheadError>()('LeaderAheadError', {
31
- minimumExpectedNum: EventSequenceNumber.Client.Composite,
32
- providedNum: EventSequenceNumber.Client.Composite,
33
- /** Generation number the client session should use for subsequent pushes */
34
- // nextGeneration: Schema.Number,
35
- }) {}
36
-
37
- export const SyncError = Schema.Union(InvalidPushError, InvalidPullError)
38
- export type SyncError = typeof SyncError.Type