@livestore/common 0.3.0-dev.2 → 0.3.0-dev.21

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 (332) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/__tests__/fixture.d.ts +21 -21
  3. package/dist/adapter-types.d.ts +97 -53
  4. package/dist/adapter-types.d.ts.map +1 -1
  5. package/dist/adapter-types.js +17 -0
  6. package/dist/adapter-types.js.map +1 -1
  7. package/dist/bounded-collections.d.ts +1 -1
  8. package/dist/bounded-collections.d.ts.map +1 -1
  9. package/dist/debug-info.d.ts +1 -1
  10. package/dist/debug-info.d.ts.map +1 -1
  11. package/dist/derived-mutations.d.ts +5 -5
  12. package/dist/derived-mutations.d.ts.map +1 -1
  13. package/dist/derived-mutations.js +3 -3
  14. package/dist/derived-mutations.js.map +1 -1
  15. package/dist/derived-mutations.test.js.map +1 -1
  16. package/dist/devtools/devtools-messages-client-session.d.ts +389 -0
  17. package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -0
  18. package/dist/devtools/devtools-messages-client-session.js +96 -0
  19. package/dist/devtools/devtools-messages-client-session.js.map +1 -0
  20. package/dist/devtools/devtools-messages-common.d.ts +61 -0
  21. package/dist/devtools/devtools-messages-common.d.ts.map +1 -0
  22. package/dist/devtools/devtools-messages-common.js +54 -0
  23. package/dist/devtools/devtools-messages-common.js.map +1 -0
  24. package/dist/devtools/devtools-messages-leader.d.ts +393 -0
  25. package/dist/devtools/devtools-messages-leader.d.ts.map +1 -0
  26. package/dist/devtools/devtools-messages-leader.js +148 -0
  27. package/dist/devtools/devtools-messages-leader.js.map +1 -0
  28. package/dist/devtools/devtools-messages.d.ts +3 -592
  29. package/dist/devtools/devtools-messages.d.ts.map +1 -1
  30. package/dist/devtools/devtools-messages.js +3 -171
  31. package/dist/devtools/devtools-messages.js.map +1 -1
  32. package/dist/devtools/devtools-sessioninfo.d.ts +28 -0
  33. package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -0
  34. package/dist/devtools/devtools-sessioninfo.js +34 -0
  35. package/dist/devtools/devtools-sessioninfo.js.map +1 -0
  36. package/dist/devtools/devtools-sessions-channel.d.ts +28 -0
  37. package/dist/devtools/devtools-sessions-channel.d.ts.map +1 -0
  38. package/dist/devtools/devtools-sessions-channel.js +34 -0
  39. package/dist/devtools/devtools-sessions-channel.js.map +1 -0
  40. package/dist/devtools/index.d.ts +35 -38
  41. package/dist/devtools/index.d.ts.map +1 -1
  42. package/dist/devtools/index.js +20 -45
  43. package/dist/devtools/index.js.map +1 -1
  44. package/dist/devtools/mod.d.ts +39 -0
  45. package/dist/devtools/mod.d.ts.map +1 -0
  46. package/dist/devtools/mod.js +27 -0
  47. package/dist/devtools/mod.js.map +1 -0
  48. package/dist/index.d.ts +2 -6
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +2 -2
  51. package/dist/index.js.map +1 -1
  52. package/dist/init-singleton-tables.d.ts +2 -2
  53. package/dist/init-singleton-tables.d.ts.map +1 -1
  54. package/dist/init-singleton-tables.js.map +1 -1
  55. package/dist/leader-thread/LeaderSyncProcessor.d.ts +39 -0
  56. package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -0
  57. package/dist/leader-thread/LeaderSyncProcessor.js +527 -0
  58. package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -0
  59. package/dist/leader-thread/apply-mutation.d.ts +5 -2
  60. package/dist/leader-thread/apply-mutation.d.ts.map +1 -1
  61. package/dist/leader-thread/apply-mutation.js +55 -35
  62. package/dist/leader-thread/apply-mutation.js.map +1 -1
  63. package/dist/leader-thread/connection.d.ts +34 -6
  64. package/dist/leader-thread/connection.d.ts.map +1 -1
  65. package/dist/leader-thread/connection.js +22 -7
  66. package/dist/leader-thread/connection.js.map +1 -1
  67. package/dist/leader-thread/leader-worker-devtools.d.ts +1 -1
  68. package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
  69. package/dist/leader-thread/leader-worker-devtools.js +147 -124
  70. package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
  71. package/dist/leader-thread/make-leader-thread-layer.d.ts +12 -11
  72. package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
  73. package/dist/leader-thread/make-leader-thread-layer.js +55 -18
  74. package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
  75. package/dist/leader-thread/mutationlog.d.ts +6 -19
  76. package/dist/leader-thread/mutationlog.d.ts.map +1 -1
  77. package/dist/leader-thread/mutationlog.js +12 -9
  78. package/dist/leader-thread/mutationlog.js.map +1 -1
  79. package/dist/leader-thread/pull-queue-set.d.ts +3 -3
  80. package/dist/leader-thread/pull-queue-set.d.ts.map +1 -1
  81. package/dist/leader-thread/pull-queue-set.js +9 -0
  82. package/dist/leader-thread/pull-queue-set.js.map +1 -1
  83. package/dist/leader-thread/recreate-db.d.ts +4 -2
  84. package/dist/leader-thread/recreate-db.d.ts.map +1 -1
  85. package/dist/leader-thread/recreate-db.js +32 -21
  86. package/dist/leader-thread/recreate-db.js.map +1 -1
  87. package/dist/leader-thread/shutdown-channel.d.ts +2 -5
  88. package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
  89. package/dist/leader-thread/shutdown-channel.js +2 -4
  90. package/dist/leader-thread/shutdown-channel.js.map +1 -1
  91. package/dist/leader-thread/types.d.ts +58 -26
  92. package/dist/leader-thread/types.d.ts.map +1 -1
  93. package/dist/leader-thread/types.js +1 -3
  94. package/dist/leader-thread/types.js.map +1 -1
  95. package/dist/mutation.d.ts +9 -2
  96. package/dist/mutation.d.ts.map +1 -1
  97. package/dist/mutation.js +5 -5
  98. package/dist/mutation.js.map +1 -1
  99. package/dist/otel.d.ts +2 -0
  100. package/dist/otel.d.ts.map +1 -1
  101. package/dist/otel.js +5 -0
  102. package/dist/otel.js.map +1 -1
  103. package/dist/query-builder/api.d.ts +3 -3
  104. package/dist/query-builder/api.d.ts.map +1 -1
  105. package/dist/query-builder/impl.d.ts +4 -4
  106. package/dist/query-builder/impl.d.ts.map +1 -1
  107. package/dist/query-builder/impl.js.map +1 -1
  108. package/dist/query-builder/impl.test.js +16 -1
  109. package/dist/query-builder/impl.test.js.map +1 -1
  110. package/dist/query-info.d.ts +3 -3
  111. package/dist/query-info.d.ts.map +1 -1
  112. package/dist/rehydrate-from-mutationlog.d.ts +5 -5
  113. package/dist/rehydrate-from-mutationlog.d.ts.map +1 -1
  114. package/dist/rehydrate-from-mutationlog.js +23 -27
  115. package/dist/rehydrate-from-mutationlog.js.map +1 -1
  116. package/dist/schema/EventId.d.ts +27 -16
  117. package/dist/schema/EventId.d.ts.map +1 -1
  118. package/dist/schema/EventId.js +36 -11
  119. package/dist/schema/EventId.js.map +1 -1
  120. package/dist/schema/EventId.test.d.ts +2 -0
  121. package/dist/schema/EventId.test.d.ts.map +1 -0
  122. package/dist/schema/EventId.test.js +11 -0
  123. package/dist/schema/EventId.test.js.map +1 -0
  124. package/dist/schema/MutationEvent.d.ts +76 -82
  125. package/dist/schema/MutationEvent.d.ts.map +1 -1
  126. package/dist/schema/MutationEvent.js +53 -20
  127. package/dist/schema/MutationEvent.js.map +1 -1
  128. package/dist/schema/db-schema/ast/sqlite.d.ts +69 -0
  129. package/dist/schema/db-schema/ast/sqlite.d.ts.map +1 -0
  130. package/dist/schema/db-schema/ast/sqlite.js +71 -0
  131. package/dist/schema/db-schema/ast/sqlite.js.map +1 -0
  132. package/dist/schema/db-schema/ast/validate.d.ts +3 -0
  133. package/dist/schema/db-schema/ast/validate.d.ts.map +1 -0
  134. package/dist/schema/db-schema/ast/validate.js +12 -0
  135. package/dist/schema/db-schema/ast/validate.js.map +1 -0
  136. package/dist/schema/db-schema/dsl/field-defs.d.ts +90 -0
  137. package/dist/schema/db-schema/dsl/field-defs.d.ts.map +1 -0
  138. package/dist/schema/db-schema/dsl/field-defs.js +87 -0
  139. package/dist/schema/db-schema/dsl/field-defs.js.map +1 -0
  140. package/dist/schema/db-schema/dsl/field-defs.test.d.ts +2 -0
  141. package/dist/schema/db-schema/dsl/field-defs.test.d.ts.map +1 -0
  142. package/dist/schema/db-schema/dsl/field-defs.test.js +29 -0
  143. package/dist/schema/db-schema/dsl/field-defs.test.js.map +1 -0
  144. package/dist/schema/db-schema/dsl/mod.d.ts +88 -0
  145. package/dist/schema/db-schema/dsl/mod.d.ts.map +1 -0
  146. package/dist/schema/db-schema/dsl/mod.js +35 -0
  147. package/dist/schema/db-schema/dsl/mod.js.map +1 -0
  148. package/dist/schema/db-schema/hash.d.ts +2 -0
  149. package/dist/schema/db-schema/hash.d.ts.map +1 -0
  150. package/dist/schema/db-schema/hash.js +14 -0
  151. package/dist/schema/db-schema/hash.js.map +1 -0
  152. package/dist/schema/db-schema/mod.d.ts +3 -0
  153. package/dist/schema/db-schema/mod.d.ts.map +1 -0
  154. package/dist/schema/db-schema/mod.js +3 -0
  155. package/dist/schema/db-schema/mod.js.map +1 -0
  156. package/dist/schema/mod.d.ts +1 -0
  157. package/dist/schema/mod.d.ts.map +1 -1
  158. package/dist/schema/mod.js +1 -0
  159. package/dist/schema/mod.js.map +1 -1
  160. package/dist/schema/mutations.d.ts +8 -9
  161. package/dist/schema/mutations.d.ts.map +1 -1
  162. package/dist/schema/mutations.js +2 -2
  163. package/dist/schema/mutations.js.map +1 -1
  164. package/dist/schema/schema-helpers.d.ts.map +1 -1
  165. package/dist/schema/schema-helpers.js +1 -1
  166. package/dist/schema/schema-helpers.js.map +1 -1
  167. package/dist/schema/schema.d.ts +5 -2
  168. package/dist/schema/schema.d.ts.map +1 -1
  169. package/dist/schema/schema.js +20 -9
  170. package/dist/schema/schema.js.map +1 -1
  171. package/dist/schema/system-tables.d.ts +65 -47
  172. package/dist/schema/system-tables.d.ts.map +1 -1
  173. package/dist/schema/system-tables.js +24 -13
  174. package/dist/schema/system-tables.js.map +1 -1
  175. package/dist/schema/table-def.d.ts +18 -24
  176. package/dist/schema/table-def.d.ts.map +1 -1
  177. package/dist/schema/table-def.js +3 -4
  178. package/dist/schema/table-def.js.map +1 -1
  179. package/dist/schema-management/common.d.ts +3 -3
  180. package/dist/schema-management/common.d.ts.map +1 -1
  181. package/dist/schema-management/common.js.map +1 -1
  182. package/dist/schema-management/migrations.d.ts +6 -6
  183. package/dist/schema-management/migrations.d.ts.map +1 -1
  184. package/dist/schema-management/migrations.js +13 -8
  185. package/dist/schema-management/migrations.js.map +1 -1
  186. package/dist/schema-management/validate-mutation-defs.d.ts.map +1 -1
  187. package/dist/schema-management/validate-mutation-defs.js +2 -2
  188. package/dist/schema-management/validate-mutation-defs.js.map +1 -1
  189. package/dist/sql-queries/misc.d.ts.map +1 -1
  190. package/dist/sql-queries/sql-queries.d.ts +1 -1
  191. package/dist/sql-queries/sql-queries.d.ts.map +1 -1
  192. package/dist/sql-queries/sql-queries.js.map +1 -1
  193. package/dist/sql-queries/sql-query-builder.d.ts +1 -1
  194. package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
  195. package/dist/sql-queries/sql-query-builder.js.map +1 -1
  196. package/dist/sql-queries/types.d.ts +2 -1
  197. package/dist/sql-queries/types.d.ts.map +1 -1
  198. package/dist/sql-queries/types.js.map +1 -1
  199. package/dist/sync/{client-session-sync-processor.d.ts → ClientSessionSyncProcessor.d.ts} +25 -14
  200. package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -0
  201. package/dist/sync/ClientSessionSyncProcessor.js +199 -0
  202. package/dist/sync/ClientSessionSyncProcessor.js.map +1 -0
  203. package/dist/sync/index.d.ts +1 -1
  204. package/dist/sync/index.d.ts.map +1 -1
  205. package/dist/sync/index.js +1 -1
  206. package/dist/sync/index.js.map +1 -1
  207. package/dist/sync/next/compact-events.d.ts.map +1 -1
  208. package/dist/sync/next/facts.d.ts.map +1 -1
  209. package/dist/sync/next/facts.js +1 -1
  210. package/dist/sync/next/facts.js.map +1 -1
  211. package/dist/sync/next/history-dag-common.d.ts +3 -4
  212. package/dist/sync/next/history-dag-common.d.ts.map +1 -1
  213. package/dist/sync/next/history-dag-common.js +3 -1
  214. package/dist/sync/next/history-dag-common.js.map +1 -1
  215. package/dist/sync/next/history-dag.d.ts.map +1 -1
  216. package/dist/sync/next/history-dag.js +1 -1
  217. package/dist/sync/next/history-dag.js.map +1 -1
  218. package/dist/sync/next/rebase-events.d.ts +6 -4
  219. package/dist/sync/next/rebase-events.d.ts.map +1 -1
  220. package/dist/sync/next/rebase-events.js +6 -3
  221. package/dist/sync/next/rebase-events.js.map +1 -1
  222. package/dist/sync/next/test/compact-events.calculator.test.js +12 -12
  223. package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
  224. package/dist/sync/next/test/compact-events.test.js +43 -43
  225. package/dist/sync/next/test/compact-events.test.js.map +1 -1
  226. package/dist/sync/next/test/mutation-fixtures.d.ts +4 -4
  227. package/dist/sync/next/test/mutation-fixtures.d.ts.map +1 -1
  228. package/dist/sync/next/test/mutation-fixtures.js +12 -16
  229. package/dist/sync/next/test/mutation-fixtures.js.map +1 -1
  230. package/dist/sync/sync.d.ts +31 -16
  231. package/dist/sync/sync.d.ts.map +1 -1
  232. package/dist/sync/sync.js +7 -3
  233. package/dist/sync/sync.js.map +1 -1
  234. package/dist/sync/syncstate.d.ts +177 -44
  235. package/dist/sync/syncstate.d.ts.map +1 -1
  236. package/dist/sync/syncstate.js +188 -56
  237. package/dist/sync/syncstate.js.map +1 -1
  238. package/dist/sync/syncstate.test.js +162 -92
  239. package/dist/sync/syncstate.test.js.map +1 -1
  240. package/dist/sync/validate-push-payload.d.ts +2 -2
  241. package/dist/sync/validate-push-payload.d.ts.map +1 -1
  242. package/dist/sync/validate-push-payload.js +2 -2
  243. package/dist/sync/validate-push-payload.js.map +1 -1
  244. package/dist/util.d.ts +2 -2
  245. package/dist/util.d.ts.map +1 -1
  246. package/dist/version.d.ts +1 -1
  247. package/dist/version.d.ts.map +1 -1
  248. package/dist/version.js +1 -1
  249. package/dist/version.js.map +1 -1
  250. package/package.json +6 -6
  251. package/src/adapter-types.ts +80 -56
  252. package/src/derived-mutations.test.ts +1 -1
  253. package/src/derived-mutations.ts +13 -9
  254. package/src/devtools/devtools-messages-client-session.ts +141 -0
  255. package/src/devtools/devtools-messages-common.ts +106 -0
  256. package/src/devtools/devtools-messages-leader.ts +192 -0
  257. package/src/devtools/devtools-messages.ts +3 -243
  258. package/src/devtools/devtools-sessioninfo.ts +99 -0
  259. package/src/devtools/mod.ts +36 -0
  260. package/src/index.ts +2 -8
  261. package/src/init-singleton-tables.ts +2 -2
  262. package/src/leader-thread/LeaderSyncProcessor.ts +833 -0
  263. package/src/leader-thread/apply-mutation.ts +87 -43
  264. package/src/leader-thread/connection.ts +54 -9
  265. package/src/leader-thread/leader-worker-devtools.ts +199 -174
  266. package/src/leader-thread/make-leader-thread-layer.ts +89 -35
  267. package/src/leader-thread/mutationlog.ts +20 -14
  268. package/src/leader-thread/pull-queue-set.ts +10 -1
  269. package/src/leader-thread/recreate-db.ts +38 -25
  270. package/src/leader-thread/shutdown-channel.ts +2 -4
  271. package/src/leader-thread/types.ts +68 -34
  272. package/src/mutation.ts +17 -7
  273. package/src/otel.ts +8 -0
  274. package/src/query-builder/api.ts +4 -4
  275. package/src/query-builder/impl.test.ts +22 -1
  276. package/src/query-builder/impl.ts +2 -2
  277. package/src/query-info.ts +3 -3
  278. package/src/rehydrate-from-mutationlog.ts +28 -34
  279. package/src/schema/EventId.test.ts +12 -0
  280. package/src/schema/EventId.ts +49 -15
  281. package/src/schema/MutationEvent.ts +78 -31
  282. package/src/schema/db-schema/ast/sqlite.ts +142 -0
  283. package/src/schema/db-schema/ast/validate.ts +13 -0
  284. package/src/schema/db-schema/dsl/__snapshots__/field-defs.test.ts.snap +206 -0
  285. package/src/schema/db-schema/dsl/field-defs.test.ts +35 -0
  286. package/src/schema/db-schema/dsl/field-defs.ts +242 -0
  287. package/src/schema/db-schema/dsl/mod.ts +195 -0
  288. package/src/schema/db-schema/hash.ts +14 -0
  289. package/src/schema/db-schema/mod.ts +2 -0
  290. package/src/schema/mod.ts +1 -0
  291. package/src/schema/mutations.ts +10 -20
  292. package/src/schema/schema-helpers.ts +1 -1
  293. package/src/schema/schema.ts +22 -10
  294. package/src/schema/system-tables.ts +24 -13
  295. package/src/schema/table-def.ts +17 -17
  296. package/src/schema-management/common.ts +3 -3
  297. package/src/schema-management/migrations.ts +19 -15
  298. package/src/schema-management/validate-mutation-defs.ts +2 -2
  299. package/src/sql-queries/sql-queries.ts +1 -1
  300. package/src/sql-queries/sql-query-builder.ts +1 -2
  301. package/src/sql-queries/types.ts +3 -1
  302. package/src/sync/ClientSessionSyncProcessor.ts +313 -0
  303. package/src/sync/index.ts +1 -1
  304. package/src/sync/next/facts.ts +1 -1
  305. package/src/sync/next/history-dag-common.ts +5 -1
  306. package/src/sync/next/history-dag.ts +1 -1
  307. package/src/sync/next/rebase-events.ts +13 -7
  308. package/src/sync/next/test/compact-events.calculator.test.ts +12 -12
  309. package/src/sync/next/test/compact-events.test.ts +43 -43
  310. package/src/sync/next/test/mutation-fixtures.ts +16 -19
  311. package/src/sync/sync.ts +26 -10
  312. package/src/sync/syncstate.test.ts +178 -98
  313. package/src/sync/syncstate.ts +170 -83
  314. package/src/sync/validate-push-payload.ts +7 -4
  315. package/src/version.ts +1 -1
  316. package/tmp/pack.tgz +0 -0
  317. package/tsconfig.json +1 -1
  318. package/dist/devtools/devtools-bridge.d.ts +0 -12
  319. package/dist/devtools/devtools-bridge.d.ts.map +0 -1
  320. package/dist/devtools/devtools-bridge.js +0 -2
  321. package/dist/devtools/devtools-bridge.js.map +0 -1
  322. package/dist/leader-thread/leader-sync-processor.d.ts +0 -47
  323. package/dist/leader-thread/leader-sync-processor.d.ts.map +0 -1
  324. package/dist/leader-thread/leader-sync-processor.js +0 -422
  325. package/dist/leader-thread/leader-sync-processor.js.map +0 -1
  326. package/dist/sync/client-session-sync-processor.d.ts.map +0 -1
  327. package/dist/sync/client-session-sync-processor.js +0 -131
  328. package/dist/sync/client-session-sync-processor.js.map +0 -1
  329. package/src/devtools/devtools-bridge.ts +0 -13
  330. package/src/devtools/index.ts +0 -48
  331. package/src/leader-thread/leader-sync-processor.ts +0 -666
  332. package/src/sync/client-session-sync-processor.ts +0 -207
@@ -1,6 +1,43 @@
1
1
  import { Schema } from '@livestore/utils/effect';
2
- import * as EventId from '../schema/EventId.js';
2
+ import { UnexpectedError } from '../adapter-types.js';
3
3
  import * as MutationEvent from '../schema/MutationEvent.js';
4
+ declare const SyncState_base: Schema.Class<SyncState, {
5
+ pending: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
6
+ rollbackTail: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
7
+ upstreamHead: Schema.Struct<{
8
+ global: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventId">, number, never>;
9
+ client: Schema.BrandSchema<number & import("effect/Brand").Brand<"ClientEventId">, number, never>;
10
+ }>;
11
+ localHead: Schema.Struct<{
12
+ global: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventId">, number, never>;
13
+ client: Schema.BrandSchema<number & import("effect/Brand").Brand<"ClientEventId">, number, never>;
14
+ }>;
15
+ }, Schema.Struct.Encoded<{
16
+ pending: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
17
+ rollbackTail: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
18
+ upstreamHead: Schema.Struct<{
19
+ global: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventId">, number, never>;
20
+ client: Schema.BrandSchema<number & import("effect/Brand").Brand<"ClientEventId">, number, never>;
21
+ }>;
22
+ localHead: Schema.Struct<{
23
+ global: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventId">, number, never>;
24
+ client: Schema.BrandSchema<number & import("effect/Brand").Brand<"ClientEventId">, number, never>;
25
+ }>;
26
+ }>, never, {
27
+ readonly pending: readonly MutationEvent.EncodedWithMeta[];
28
+ } & {
29
+ readonly upstreamHead: {
30
+ readonly global: number & import("effect/Brand").Brand<"GlobalEventId">;
31
+ readonly client: number & import("effect/Brand").Brand<"ClientEventId">;
32
+ };
33
+ } & {
34
+ readonly localHead: {
35
+ readonly global: number & import("effect/Brand").Brand<"GlobalEventId">;
36
+ readonly client: number & import("effect/Brand").Brand<"ClientEventId">;
37
+ };
38
+ } & {
39
+ readonly rollbackTail: readonly MutationEvent.EncodedWithMeta[];
40
+ }, {}, {}>;
4
41
  /**
5
42
  * SyncState represents the current sync state of a sync node relative to an upstream node.
6
43
  * Events flow from local to upstream, with each state maintaining its own event head.
@@ -36,35 +73,20 @@ import * as MutationEvent from '../schema/MutationEvent.js';
36
73
  * The `updateSyncState` function processes updates to the sync state based on incoming payloads,
37
74
  * handling cases such as upstream rebase, advance, local push, and rollback tail trimming.
38
75
  */
39
- export interface SyncState {
40
- pending: ReadonlyArray<MutationEvent.EncodedWithMeta>;
41
- rollbackTail: ReadonlyArray<MutationEvent.EncodedWithMeta>;
42
- upstreamHead: EventId.EventId;
43
- localHead: EventId.EventId;
76
+ export declare class SyncState extends SyncState_base {
77
+ toJSON: () => any;
44
78
  }
45
- export declare const SyncState: Schema.Struct<{
46
- pending: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
47
- rollbackTail: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
48
- upstreamHead: Schema.Struct<{
49
- global: typeof Schema.Number;
50
- local: typeof Schema.Number;
51
- }>;
52
- localHead: Schema.Struct<{
53
- global: typeof Schema.Number;
54
- local: typeof Schema.Number;
55
- }>;
56
- }>;
57
79
  declare const PayloadUpstreamRebase_base: Schema.TaggedStruct<"upstream-rebase", {
58
80
  /** Rollback until this event in the rollback tail (inclusive). Starting from the end of the rollback tail. */
59
81
  rollbackUntil: Schema.Struct<{
60
- global: typeof Schema.Number;
61
- local: typeof Schema.Number;
82
+ global: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventId">, number, never>;
83
+ client: Schema.BrandSchema<number & import("effect/Brand").Brand<"ClientEventId">, number, never>;
62
84
  }>;
63
85
  newEvents: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
64
86
  /** Trim rollback tail up to this event (inclusive). */
65
87
  trimRollbackUntil: Schema.optional<Schema.Struct<{
66
- global: typeof Schema.Number;
67
- local: typeof Schema.Number;
88
+ global: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventId">, number, never>;
89
+ client: Schema.BrandSchema<number & import("effect/Brand").Brand<"ClientEventId">, number, never>;
68
90
  }>>;
69
91
  }>;
70
92
  export declare class PayloadUpstreamRebase extends PayloadUpstreamRebase_base {
@@ -73,8 +95,8 @@ declare const PayloadUpstreamAdvance_base: Schema.TaggedStruct<"upstream-advance
73
95
  newEvents: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
74
96
  /** Trim rollback tail up to this event (inclusive). */
75
97
  trimRollbackUntil: Schema.optional<Schema.Struct<{
76
- global: typeof Schema.Number;
77
- local: typeof Schema.Number;
98
+ global: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventId">, number, never>;
99
+ client: Schema.BrandSchema<number & import("effect/Brand").Brand<"ClientEventId">, number, never>;
78
100
  }>>;
79
101
  }>;
80
102
  export declare class PayloadUpstreamAdvance extends PayloadUpstreamAdvance_base {
@@ -89,28 +111,139 @@ export declare class Payload extends Payload_base {
89
111
  }
90
112
  export declare const PayloadUpstream: Schema.Union<[typeof PayloadUpstreamRebase, typeof PayloadUpstreamAdvance]>;
91
113
  export type PayloadUpstream = typeof PayloadUpstream.Type;
92
- export type UpdateResultAdvance = {
93
- _tag: 'advance';
94
- newSyncState: SyncState;
95
- previousSyncState: SyncState;
114
+ declare const UpdateContext_base: Schema.Class<UpdateContext, {
115
+ payload: typeof Payload;
116
+ syncState: typeof SyncState;
117
+ }, Schema.Struct.Encoded<{
118
+ payload: typeof Payload;
119
+ syncState: typeof SyncState;
120
+ }>, never, {
121
+ readonly payload: {
122
+ readonly _tag: "upstream-rebase";
123
+ readonly rollbackUntil: {
124
+ readonly global: number & import("effect/Brand").Brand<"GlobalEventId">;
125
+ readonly client: number & import("effect/Brand").Brand<"ClientEventId">;
126
+ };
127
+ readonly newEvents: readonly MutationEvent.EncodedWithMeta[];
128
+ readonly trimRollbackUntil?: {
129
+ readonly global: number & import("effect/Brand").Brand<"GlobalEventId">;
130
+ readonly client: number & import("effect/Brand").Brand<"ClientEventId">;
131
+ } | undefined;
132
+ } | {
133
+ readonly _tag: "upstream-advance";
134
+ readonly newEvents: readonly MutationEvent.EncodedWithMeta[];
135
+ readonly trimRollbackUntil?: {
136
+ readonly global: number & import("effect/Brand").Brand<"GlobalEventId">;
137
+ readonly client: number & import("effect/Brand").Brand<"ClientEventId">;
138
+ } | undefined;
139
+ } | {
140
+ readonly _tag: "local-push";
141
+ readonly newEvents: readonly MutationEvent.EncodedWithMeta[];
142
+ };
143
+ } & {
144
+ readonly syncState: SyncState;
145
+ }, {}, {}>;
146
+ /** Only used for debugging purposes */
147
+ export declare class UpdateContext extends UpdateContext_base {
148
+ toJSON: () => any;
149
+ }
150
+ declare const UpdateResultAdvance_base: Schema.Class<UpdateResultAdvance, {
151
+ _tag: Schema.Literal<["advance"]>;
152
+ newSyncState: typeof SyncState;
153
+ /** Events which weren't pending before the update */
154
+ newEvents: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
155
+ updateContext: typeof UpdateContext;
156
+ }, Schema.Struct.Encoded<{
157
+ _tag: Schema.Literal<["advance"]>;
158
+ newSyncState: typeof SyncState;
96
159
  /** Events which weren't pending before the update */
97
- newEvents: ReadonlyArray<MutationEvent.EncodedWithMeta>;
98
- };
99
- export type UpdateResultRebase = {
100
- _tag: 'rebase';
101
- newSyncState: SyncState;
102
- previousSyncState: SyncState;
160
+ newEvents: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
161
+ updateContext: typeof UpdateContext;
162
+ }>, never, {
163
+ readonly _tag: "advance";
164
+ } & {
165
+ readonly newEvents: readonly MutationEvent.EncodedWithMeta[];
166
+ } & {
167
+ readonly newSyncState: SyncState;
168
+ } & {
169
+ readonly updateContext: UpdateContext;
170
+ }, {}, {}>;
171
+ export declare class UpdateResultAdvance extends UpdateResultAdvance_base {
172
+ toJSON: () => any;
173
+ }
174
+ declare const UpdateResultRebase_base: Schema.Class<UpdateResultRebase, {
175
+ _tag: Schema.Literal<["rebase"]>;
176
+ newSyncState: typeof SyncState;
177
+ /** Events which weren't pending before the update */
178
+ newEvents: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
179
+ eventsToRollback: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
180
+ updateContext: typeof UpdateContext;
181
+ }, Schema.Struct.Encoded<{
182
+ _tag: Schema.Literal<["rebase"]>;
183
+ newSyncState: typeof SyncState;
103
184
  /** Events which weren't pending before the update */
104
- newEvents: ReadonlyArray<MutationEvent.EncodedWithMeta>;
105
- eventsToRollback: ReadonlyArray<MutationEvent.EncodedWithMeta>;
106
- };
107
- export type UpdateResultReject = {
108
- _tag: 'reject';
109
- previousSyncState: SyncState;
185
+ newEvents: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
186
+ eventsToRollback: Schema.Array$<typeof MutationEvent.EncodedWithMeta>;
187
+ updateContext: typeof UpdateContext;
188
+ }>, never, {
189
+ readonly _tag: "rebase";
190
+ } & {
191
+ readonly newEvents: readonly MutationEvent.EncodedWithMeta[];
192
+ } & {
193
+ readonly newSyncState: SyncState;
194
+ } & {
195
+ readonly updateContext: UpdateContext;
196
+ } & {
197
+ readonly eventsToRollback: readonly MutationEvent.EncodedWithMeta[];
198
+ }, {}, {}>;
199
+ export declare class UpdateResultRebase extends UpdateResultRebase_base {
200
+ toJSON: () => any;
201
+ }
202
+ declare const UpdateResultReject_base: Schema.Class<UpdateResultReject, {
203
+ _tag: Schema.Literal<["reject"]>;
204
+ /** The minimum id that the new events must have */
205
+ expectedMinimumId: Schema.Struct<{
206
+ global: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventId">, number, never>;
207
+ client: Schema.BrandSchema<number & import("effect/Brand").Brand<"ClientEventId">, number, never>;
208
+ }>;
209
+ updateContext: typeof UpdateContext;
210
+ }, Schema.Struct.Encoded<{
211
+ _tag: Schema.Literal<["reject"]>;
110
212
  /** The minimum id that the new events must have */
111
- expectedMinimumId: EventId.EventId;
112
- };
113
- export type UpdateResult = UpdateResultAdvance | UpdateResultRebase | UpdateResultReject;
213
+ expectedMinimumId: Schema.Struct<{
214
+ global: Schema.BrandSchema<number & import("effect/Brand").Brand<"GlobalEventId">, number, never>;
215
+ client: Schema.BrandSchema<number & import("effect/Brand").Brand<"ClientEventId">, number, never>;
216
+ }>;
217
+ updateContext: typeof UpdateContext;
218
+ }>, never, {
219
+ readonly _tag: "reject";
220
+ } & {
221
+ readonly updateContext: UpdateContext;
222
+ } & {
223
+ readonly expectedMinimumId: {
224
+ readonly global: number & import("effect/Brand").Brand<"GlobalEventId">;
225
+ readonly client: number & import("effect/Brand").Brand<"ClientEventId">;
226
+ };
227
+ }, {}, {}>;
228
+ export declare class UpdateResultReject extends UpdateResultReject_base {
229
+ toJSON: () => any;
230
+ }
231
+ declare const UpdateResultUnexpectedError_base: Schema.Class<UpdateResultUnexpectedError, {
232
+ _tag: Schema.Literal<["unexpected-error"]>;
233
+ cause: typeof UnexpectedError;
234
+ }, Schema.Struct.Encoded<{
235
+ _tag: Schema.Literal<["unexpected-error"]>;
236
+ cause: typeof UnexpectedError;
237
+ }>, never, {
238
+ readonly _tag: "unexpected-error";
239
+ } & {
240
+ readonly cause: UnexpectedError;
241
+ }, {}, {}>;
242
+ export declare class UpdateResultUnexpectedError extends UpdateResultUnexpectedError_base {
243
+ }
244
+ declare const UpdateResult_base: Schema.Union<[typeof UpdateResultAdvance, typeof UpdateResultRebase, typeof UpdateResultReject, typeof UpdateResultUnexpectedError]>;
245
+ export declare class UpdateResult extends UpdateResult_base {
246
+ }
114
247
  export declare const updateSyncState: ({ syncState, payload, isLocalEvent, isEqualEvent, ignoreLocalEvents, }: {
115
248
  syncState: SyncState;
116
249
  payload: typeof Payload.Type;
@@ -118,6 +251,6 @@ export declare const updateSyncState: ({ syncState, payload, isLocalEvent, isEqu
118
251
  isEqualEvent: (a: MutationEvent.EncodedWithMeta, b: MutationEvent.EncodedWithMeta) => boolean;
119
252
  /** This is used in the leader which should ignore local events when receiving an upstream-advance payload */
120
253
  ignoreLocalEvents?: boolean;
121
- }) => UpdateResult;
254
+ }) => typeof UpdateResult.Type;
122
255
  export {};
123
256
  //# sourceMappingURL=syncstate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"syncstate.d.ts","sourceRoot":"","sources":["../../src/sync/syncstate.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAE/D,OAAO,KAAK,OAAO,MAAM,sBAAsB,CAAA;AAC/C,OAAO,KAAK,aAAa,MAAM,4BAA4B,CAAA;AAE3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,aAAa,CAAC,aAAa,CAAC,eAAe,CAAC,CAAA;IACrD,YAAY,EAAE,aAAa,CAAC,aAAa,CAAC,eAAe,CAAC,CAAA;IAC1D,YAAY,EAAE,OAAO,CAAC,OAAO,CAAA;IAC7B,SAAS,EAAE,OAAO,CAAC,OAAO,CAAA;CAC3B;AAED,eAAO,MAAM,SAAS;;;;;;;;;;;EAKgB,CAAA;;IAGpC,8GAA8G;;;;;;IAG9G,uDAAuD;;;;;;AAJzD,qBAAa,qBAAsB,SAAQ,0BAMzC;CAAG;;;IAIH,uDAAuD;;;;;;AAFzD,qBAAa,sBAAuB,SAAQ,2BAI1C;CAAG;;;;AAEL,qBAAa,gBAAiB,SAAQ,qBAEpC;CAAG;;AAEL,qBAAa,OAAQ,SAAQ,YAA6E;CAAG;AAE7G,eAAO,MAAM,eAAe,6EAA8D,CAAA;AAE1F,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,IAAI,CAAA;AAEzD,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,SAAS,CAAA;IACf,YAAY,EAAE,SAAS,CAAA;IACvB,iBAAiB,EAAE,SAAS,CAAA;IAC5B,qDAAqD;IACrD,SAAS,EAAE,aAAa,CAAC,aAAa,CAAC,eAAe,CAAC,CAAA;CACxD,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,QAAQ,CAAA;IACd,YAAY,EAAE,SAAS,CAAA;IACvB,iBAAiB,EAAE,SAAS,CAAA;IAC5B,qDAAqD;IACrD,SAAS,EAAE,aAAa,CAAC,aAAa,CAAC,eAAe,CAAC,CAAA;IACvD,gBAAgB,EAAE,aAAa,CAAC,aAAa,CAAC,eAAe,CAAC,CAAA;CAC/D,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,QAAQ,CAAA;IACd,iBAAiB,EAAE,SAAS,CAAA;IAC5B,mDAAmD;IACnD,iBAAiB,EAAE,OAAO,CAAC,OAAO,CAAA;CACnC,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,mBAAmB,GAAG,kBAAkB,GAAG,kBAAkB,CAAA;AAExF,eAAO,MAAM,eAAe,2EAMzB;IACD,SAAS,EAAE,SAAS,CAAA;IACpB,OAAO,EAAE,OAAO,OAAO,CAAC,IAAI,CAAA;IAC5B,YAAY,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,eAAe,KAAK,OAAO,CAAA;IAC/D,YAAY,EAAE,CAAC,CAAC,EAAE,aAAa,CAAC,eAAe,EAAE,CAAC,EAAE,aAAa,CAAC,eAAe,KAAK,OAAO,CAAA;IAC7F,6GAA6G;IAC7G,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B,KAAG,YA+MH,CAAA"}
1
+ {"version":3,"file":"syncstate.d.ts","sourceRoot":"","sources":["../../src/sync/syncstate.ts"],"names":[],"mappings":"AACA,OAAO,EAAwB,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAEtE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAErD,OAAO,KAAK,aAAa,MAAM,4BAA4B,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAE3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,qBAAa,SAAU,SAAQ,cAK7B;IACA,MAAM,QAAO,GAAG,CAOf;CACF;;IAGC,8GAA8G;;;;;;IAG9G,uDAAuD;;;;;;AAJzD,qBAAa,qBAAsB,SAAQ,0BAMzC;CAAG;;;IAIH,uDAAuD;;;;;;AAFzD,qBAAa,sBAAuB,SAAQ,2BAI1C;CAAG;;;;AAEL,qBAAa,gBAAiB,SAAQ,qBAEpC;CAAG;;AAEL,qBAAa,OAAQ,SAAQ,YAA6E;CAAG;AAE7G,eAAO,MAAM,eAAe,6EAA8D,CAAA;AAE1F,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,IAAI,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEzD,uCAAuC;AACvC,qBAAa,aAAc,SAAQ,kBAGjC;IACA,MAAM,QAAO,GAAG,CAoBf;CACF;;;;IAKC,qDAAqD;;;;;;IAArD,qDAAqD;;;;;;;;;;;;AAHvD,qBAAa,mBAAoB,SAAQ,wBAMvC;IACA,MAAM,QAAO,GAAG,CAOf;CACF;;;;IAKC,qDAAqD;;;;;;;IAArD,qDAAqD;;;;;;;;;;;;;;;AAHvD,qBAAa,kBAAmB,SAAQ,uBAOtC;IACA,MAAM,QAAO,GAAG,CAQf;CACF;;;IAIC,mDAAmD;;;;;;;;IAAnD,mDAAmD;;;;;;;;;;;;;;;;AAFrD,qBAAa,kBAAmB,SAAQ,uBAKtC;IACA,MAAM,QAAO,GAAG,CAMf;CACF;;;;;;;;;;;;AAED,qBAAa,2BAA4B,SAAQ,gCAK/C;CAAG;;AAEL,qBAAa,YAAa,SAAQ,iBAKjC;CAAG;AAQJ,eAAO,MAAM,eAAe,GAAI,wEAM7B;IACD,SAAS,EAAE,SAAS,CAAA;IACpB,OAAO,EAAE,OAAO,OAAO,CAAC,IAAI,CAAA;IAC5B,YAAY,EAAE,CAAC,KAAK,EAAE,aAAa,CAAC,eAAe,KAAK,OAAO,CAAA;IAC/D,YAAY,EAAE,CAAC,CAAC,EAAE,aAAa,CAAC,eAAe,EAAE,CAAC,EAAE,aAAa,CAAC,eAAe,KAAK,OAAO,CAAA;IAC7F,6GAA6G;IAC7G,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B,KAAG,OAAO,YAAY,CAAC,IAiNvB,CAAA"}
@@ -1,13 +1,58 @@
1
- import { shouldNeverHappen } from '@livestore/utils';
2
- import { ReadonlyArray, Schema } from '@livestore/utils/effect';
1
+ import { casesHandled } from '@livestore/utils';
2
+ import { Match, ReadonlyArray, Schema } from '@livestore/utils/effect';
3
+ import { UnexpectedError } from '../adapter-types.js';
3
4
  import * as EventId from '../schema/EventId.js';
4
5
  import * as MutationEvent from '../schema/MutationEvent.js';
5
- export const SyncState = Schema.Struct({
6
+ /**
7
+ * SyncState represents the current sync state of a sync node relative to an upstream node.
8
+ * Events flow from local to upstream, with each state maintaining its own event head.
9
+ *
10
+ * Event Chain Structure:
11
+ * ```
12
+ * +-------------------------+------------------------+
13
+ * | ROLLBACK TAIL | PENDING EVENTS |
14
+ * +-------------------------+------------------------+
15
+ * ▼ ▼
16
+ * Upstream Head Local Head
17
+ * Example: (0,0), (0,1), (1,0) (1,1), (1,2), (2,0)
18
+ * ```
19
+ *
20
+ * State:
21
+ * - **Pending Events**: Events awaiting acknowledgment from the upstream.
22
+ * - Can be confirmed or rejected by the upstream.
23
+ * - Subject to rebase if rejected.
24
+ * - **Rollback Tail**: Events that are kept around temporarily for potential rollback until confirmed by upstream.
25
+ *
26
+ * Payloads:
27
+ * - `PayloadUpstreamRebase`: Upstream has performed a rebase, so downstream must roll back to the specified event
28
+ * and rebase the pending events on top of the new events.
29
+ * - `PayloadUpstreamAdvance`: Upstream has advanced, so downstream must rebase the pending events on top of the new events.
30
+ * - `PayloadUpstreamTrimRollbackTail`: Upstream has advanced, so downstream can trim the rollback tail.
31
+ * - `PayloadLocalPush`: Local push payload
32
+ *
33
+ * Invariants:
34
+ * 1. **Chain Continuity**: Each event must reference its immediate parent.
35
+ * 2. **Head Ordering**: Upstream Head ≤ Local Head.
36
+ * 3. **ID Sequence**: Must follow the pattern (1,0)→(1,1)→(1,2)→(2,0).
37
+ *
38
+ * The `updateSyncState` function processes updates to the sync state based on incoming payloads,
39
+ * handling cases such as upstream rebase, advance, local push, and rollback tail trimming.
40
+ */
41
+ export class SyncState extends Schema.Class('SyncState')({
6
42
  pending: Schema.Array(MutationEvent.EncodedWithMeta),
7
43
  rollbackTail: Schema.Array(MutationEvent.EncodedWithMeta),
8
44
  upstreamHead: EventId.EventId,
9
45
  localHead: EventId.EventId,
10
- }).annotations({ title: 'SyncState' });
46
+ }) {
47
+ toJSON = () => {
48
+ return {
49
+ pending: this.pending.map((e) => e.toJSON()),
50
+ rollbackTail: this.rollbackTail.map((e) => e.toJSON()),
51
+ upstreamHead: `(${this.upstreamHead.global},${this.upstreamHead.client})`,
52
+ localHead: `(${this.localHead.global},${this.localHead.client})`,
53
+ };
54
+ };
55
+ }
11
56
  export class PayloadUpstreamRebase extends Schema.TaggedStruct('upstream-rebase', {
12
57
  /** Rollback until this event in the rollback tail (inclusive). Starting from the end of the rollback tail. */
13
58
  rollbackUntil: EventId.EventId,
@@ -29,6 +74,87 @@ export class PayloadLocalPush extends Schema.TaggedStruct('local-push', {
29
74
  export class Payload extends Schema.Union(PayloadUpstreamRebase, PayloadUpstreamAdvance, PayloadLocalPush) {
30
75
  }
31
76
  export const PayloadUpstream = Schema.Union(PayloadUpstreamRebase, PayloadUpstreamAdvance);
77
+ /** Only used for debugging purposes */
78
+ export class UpdateContext extends Schema.Class('UpdateContext')({
79
+ payload: Payload,
80
+ syncState: SyncState,
81
+ }) {
82
+ toJSON = () => {
83
+ const payload = Match.value(this.payload).pipe(Match.tag('local-push', () => ({
84
+ _tag: 'local-push',
85
+ newEvents: this.payload.newEvents.map((e) => e.toJSON()),
86
+ })), Match.tag('upstream-advance', () => ({
87
+ _tag: 'upstream-advance',
88
+ newEvents: this.payload.newEvents.map((e) => e.toJSON()),
89
+ })), Match.tag('upstream-rebase', () => ({
90
+ _tag: 'upstream-rebase',
91
+ newEvents: this.payload.newEvents.map((e) => e.toJSON()),
92
+ })), Match.exhaustive);
93
+ return {
94
+ payload,
95
+ syncState: this.syncState.toJSON(),
96
+ };
97
+ };
98
+ }
99
+ export class UpdateResultAdvance extends Schema.Class('UpdateResultAdvance')({
100
+ _tag: Schema.Literal('advance'),
101
+ newSyncState: SyncState,
102
+ /** Events which weren't pending before the update */
103
+ newEvents: Schema.Array(MutationEvent.EncodedWithMeta),
104
+ updateContext: UpdateContext,
105
+ }) {
106
+ toJSON = () => {
107
+ return {
108
+ _tag: this._tag,
109
+ newSyncState: this.newSyncState.toJSON(),
110
+ newEvents: this.newEvents.map((e) => e.toJSON()),
111
+ updateContext: this.updateContext.toJSON(),
112
+ };
113
+ };
114
+ }
115
+ export class UpdateResultRebase extends Schema.Class('UpdateResultRebase')({
116
+ _tag: Schema.Literal('rebase'),
117
+ newSyncState: SyncState,
118
+ /** Events which weren't pending before the update */
119
+ newEvents: Schema.Array(MutationEvent.EncodedWithMeta),
120
+ eventsToRollback: Schema.Array(MutationEvent.EncodedWithMeta),
121
+ updateContext: UpdateContext,
122
+ }) {
123
+ toJSON = () => {
124
+ return {
125
+ _tag: this._tag,
126
+ newSyncState: this.newSyncState.toJSON(),
127
+ newEvents: this.newEvents.map((e) => e.toJSON()),
128
+ eventsToRollback: this.eventsToRollback.map((e) => e.toJSON()),
129
+ updateContext: this.updateContext.toJSON(),
130
+ };
131
+ };
132
+ }
133
+ export class UpdateResultReject extends Schema.Class('UpdateResultReject')({
134
+ _tag: Schema.Literal('reject'),
135
+ /** The minimum id that the new events must have */
136
+ expectedMinimumId: EventId.EventId,
137
+ updateContext: UpdateContext,
138
+ }) {
139
+ toJSON = () => {
140
+ return {
141
+ _tag: this._tag,
142
+ expectedMinimumId: `(${this.expectedMinimumId.global},${this.expectedMinimumId.client})`,
143
+ updateContext: this.updateContext.toJSON(),
144
+ };
145
+ };
146
+ }
147
+ export class UpdateResultUnexpectedError extends Schema.Class('UpdateResultUnexpectedError')({
148
+ _tag: Schema.Literal('unexpected-error'),
149
+ cause: UnexpectedError,
150
+ }) {
151
+ }
152
+ export class UpdateResult extends Schema.Union(UpdateResultAdvance, UpdateResultRebase, UpdateResultReject, UpdateResultUnexpectedError) {
153
+ }
154
+ const unexpectedError = (cause) => UpdateResultUnexpectedError.make({
155
+ _tag: 'unexpected-error',
156
+ cause: new UnexpectedError({ cause }),
157
+ });
32
158
  export const updateSyncState = ({ syncState, payload, isLocalEvent, isEqualEvent, ignoreLocalEvents = false, }) => {
33
159
  const trimRollbackTail = (rollbackTail) => {
34
160
  const trimRollbackUntil = payload._tag === 'local-push' ? undefined : payload.trimRollbackUntil;
@@ -39,12 +165,13 @@ export const updateSyncState = ({ syncState, payload, isLocalEvent, isEqualEvent
39
165
  return [];
40
166
  return rollbackTail.slice(index + 1);
41
167
  };
168
+ const updateContext = UpdateContext.make({ payload, syncState });
42
169
  switch (payload._tag) {
43
170
  case 'upstream-rebase': {
44
171
  // Find the index of the rollback event in the rollback tail
45
172
  const rollbackIndex = syncState.rollbackTail.findIndex((event) => EventId.isEqual(event.id, payload.rollbackUntil));
46
173
  if (rollbackIndex === -1) {
47
- return shouldNeverHappen(`Rollback event not found in rollback tail. Rollback until: [${payload.rollbackUntil.global},${payload.rollbackUntil.local}]. Rollback tail: [${syncState.rollbackTail.map((e) => e.toString()).join(', ')}]`);
174
+ return unexpectedError(`Rollback event not found in rollback tail. Rollback until: [${payload.rollbackUntil.global},${payload.rollbackUntil.client}]. Rollback tail: [${syncState.rollbackTail.map((e) => e.toString()).join(', ')}]`);
48
175
  }
49
176
  const eventsToRollback = [...syncState.rollbackTail.slice(rollbackIndex), ...syncState.pending];
50
177
  // Get the last new event's ID as the new upstream head
@@ -55,39 +182,43 @@ export const updateSyncState = ({ syncState, payload, isLocalEvent, isEqualEvent
55
182
  baseEventId: newUpstreamHead,
56
183
  isLocalEvent,
57
184
  });
58
- return {
185
+ return UpdateResultRebase.make({
59
186
  _tag: 'rebase',
60
- newSyncState: {
187
+ newSyncState: new SyncState({
61
188
  pending: rebasedPending,
62
189
  rollbackTail: trimRollbackTail([...syncState.rollbackTail.slice(0, rollbackIndex), ...payload.newEvents]),
63
190
  upstreamHead: newUpstreamHead,
64
191
  localHead: rebasedPending.at(-1)?.id ?? newUpstreamHead,
65
- },
66
- previousSyncState: syncState,
67
- newEvents: payload.newEvents,
192
+ }),
193
+ newEvents: [...payload.newEvents, ...rebasedPending],
68
194
  eventsToRollback,
69
- };
195
+ updateContext,
196
+ });
70
197
  }
71
198
  case 'upstream-advance': {
72
199
  if (payload.newEvents.length === 0) {
73
- return {
200
+ return UpdateResultAdvance.make({
74
201
  _tag: 'advance',
75
- newSyncState: {
202
+ newSyncState: new SyncState({
76
203
  pending: syncState.pending,
77
204
  rollbackTail: trimRollbackTail(syncState.rollbackTail),
78
205
  upstreamHead: syncState.upstreamHead,
79
206
  localHead: syncState.localHead,
80
- },
81
- previousSyncState: syncState,
207
+ }),
82
208
  newEvents: [],
83
- };
209
+ updateContext,
210
+ });
84
211
  }
85
212
  // Validate that newEvents are sorted in ascending order by eventId
86
213
  for (let i = 1; i < payload.newEvents.length; i++) {
87
214
  if (EventId.isGreaterThan(payload.newEvents[i - 1].id, payload.newEvents[i].id)) {
88
- return shouldNeverHappen('Events must be sorted in ascending order by eventId');
215
+ return unexpectedError(`Events must be sorted in ascending order by eventId. Received: [${payload.newEvents.map((e) => `(${e.id.global},${e.id.client})`).join(', ')}]`);
89
216
  }
90
217
  }
218
+ // Validate that incoming events are larger than upstream head
219
+ if (EventId.isGreaterThan(syncState.upstreamHead, payload.newEvents[0].id)) {
220
+ return unexpectedError(`Incoming events must be greater than upstream head. Expected greater than: [${syncState.upstreamHead.global},${syncState.upstreamHead.client}]. Received: [${payload.newEvents.map((e) => `(${e.id.global},${e.id.client})`).join(', ')}]`);
221
+ }
91
222
  const newUpstreamHead = payload.newEvents.at(-1).id;
92
223
  const divergentPendingIndex = findDivergencePoint({
93
224
  existingEvents: syncState.pending,
@@ -97,8 +228,8 @@ export const updateSyncState = ({ syncState, payload, isLocalEvent, isEqualEvent
97
228
  ignoreLocalEvents,
98
229
  });
99
230
  if (divergentPendingIndex === -1) {
100
- const pendingEventIds = new Set(syncState.pending.map((e) => `${e.id.global},${e.id.local}`));
101
- const newEvents = payload.newEvents.filter((e) => !pendingEventIds.has(`${e.id.global},${e.id.local}`));
231
+ const pendingEventIds = new Set(syncState.pending.map((e) => `${e.id.global},${e.id.client}`));
232
+ const newEvents = payload.newEvents.filter((e) => !pendingEventIds.has(`${e.id.global},${e.id.client}`));
102
233
  // In the case where the incoming events are a subset of the pending events,
103
234
  // we need to split the pending events into two groups:
104
235
  // - pendingMatching: The pending events up to point where they match the incoming events
@@ -118,24 +249,24 @@ export const updateSyncState = ({ syncState, payload, isLocalEvent, isEqualEvent
118
249
  });
119
250
  const seenEventIds = new Set();
120
251
  const pendingAndNewEvents = [...pendingMatching, ...payload.newEvents].filter((event) => {
121
- const eventIdStr = `${event.id.global},${event.id.local}`;
252
+ const eventIdStr = `${event.id.global},${event.id.client}`;
122
253
  if (seenEventIds.has(eventIdStr)) {
123
254
  return false;
124
255
  }
125
256
  seenEventIds.add(eventIdStr);
126
257
  return true;
127
258
  });
128
- return {
259
+ return UpdateResultAdvance.make({
129
260
  _tag: 'advance',
130
- newSyncState: {
261
+ newSyncState: new SyncState({
131
262
  pending: pendingRemaining,
132
263
  rollbackTail: trimRollbackTail([...syncState.rollbackTail, ...pendingAndNewEvents]),
133
264
  upstreamHead: newUpstreamHead,
134
265
  localHead: pendingRemaining.at(-1)?.id ?? newUpstreamHead,
135
- },
136
- previousSyncState: syncState,
266
+ }),
137
267
  newEvents,
138
- };
268
+ updateContext,
269
+ });
139
270
  }
140
271
  else {
141
272
  const divergentPending = syncState.pending.slice(divergentPendingIndex);
@@ -151,63 +282,56 @@ export const updateSyncState = ({ syncState, payload, isLocalEvent, isEqualEvent
151
282
  isLocalEvent,
152
283
  ignoreLocalEvents,
153
284
  });
154
- return {
285
+ return UpdateResultRebase.make({
155
286
  _tag: 'rebase',
156
- newSyncState: {
287
+ newSyncState: new SyncState({
157
288
  pending: rebasedPending,
158
289
  rollbackTail: trimRollbackTail([...syncState.rollbackTail, ...payload.newEvents]),
159
290
  upstreamHead: newUpstreamHead,
160
291
  localHead: rebasedPending.at(-1).id,
161
- },
162
- previousSyncState: syncState,
292
+ }),
163
293
  newEvents: [...payload.newEvents.slice(divergentNewEventsIndex), ...rebasedPending],
164
294
  eventsToRollback: [...syncState.rollbackTail, ...divergentPending],
165
- };
295
+ updateContext,
296
+ });
166
297
  }
167
298
  }
168
299
  case 'local-push': {
169
300
  if (payload.newEvents.length === 0) {
170
- return { _tag: 'advance', newSyncState: syncState, previousSyncState: syncState, newEvents: [] };
301
+ return UpdateResultAdvance.make({
302
+ _tag: 'advance',
303
+ newSyncState: syncState,
304
+ newEvents: [],
305
+ updateContext,
306
+ });
171
307
  }
172
308
  const newEventsFirst = payload.newEvents.at(0);
173
309
  const invalidEventId = EventId.isGreaterThan(newEventsFirst.id, syncState.localHead) === false;
174
310
  if (invalidEventId) {
175
311
  const expectedMinimumId = EventId.nextPair(syncState.localHead, true).id;
176
- return { _tag: 'reject', previousSyncState: syncState, expectedMinimumId };
312
+ return UpdateResultReject.make({
313
+ _tag: 'reject',
314
+ expectedMinimumId,
315
+ updateContext,
316
+ });
177
317
  }
178
318
  else {
179
- return {
319
+ return UpdateResultAdvance.make({
180
320
  _tag: 'advance',
181
- newSyncState: {
321
+ newSyncState: new SyncState({
182
322
  pending: [...syncState.pending, ...payload.newEvents],
183
323
  rollbackTail: syncState.rollbackTail,
184
324
  upstreamHead: syncState.upstreamHead,
185
325
  localHead: payload.newEvents.at(-1).id,
186
- },
187
- previousSyncState: syncState,
326
+ }),
188
327
  newEvents: payload.newEvents,
189
- };
328
+ updateContext,
329
+ });
190
330
  }
191
331
  }
192
- // case 'upstream-trim-rollback-tail': {
193
- // // Find the index of the new rollback start in the rollback tail
194
- // const startIndex = syncState.rollbackTail.findIndex((event) => eventIdsEqual(event.id, payload.trimRollbackUntil))
195
- // if (startIndex === -1) {
196
- // return shouldNeverHappen('New rollback start event not found in rollback tail')
197
- // }
198
- // // Keep only the events from the start index onwards
199
- // const newRollbackTail = syncState.rollbackTail.slice(startIndex)
200
- // return {
201
- // _tag: 'advance',
202
- // syncState: {
203
- // pending: syncState.pending,
204
- // rollbackTail: newRollbackTail,
205
- // upstreamHead: syncState.upstreamHead,
206
- // localHead: syncState.localHead,
207
- // },
208
- // newEvents: [],
209
- // }
210
- // }
332
+ default: {
333
+ casesHandled(payload);
334
+ }
211
335
  }
212
336
  };
213
337
  /**
@@ -245,4 +369,12 @@ const rebaseEvents = ({ events, baseEventId, isLocalEvent, }) => {
245
369
  return newEvent;
246
370
  });
247
371
  };
372
+ /**
373
+ * TODO: Implement this
374
+ *
375
+ * In certain scenarios e.g. when the client session has a queue of upstream update results,
376
+ * it could make sense to "flatten" update results into a single update result which the client session
377
+ * can process more efficiently which avoids push-threshing
378
+ */
379
+ const _flattenUpdateResults = (_updateResults) => { };
248
380
  //# sourceMappingURL=syncstate.js.map