@livestore/common 0.3.0-dev.3 → 0.3.0-dev.30

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 (426) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/__tests__/fixture.d.ts +83 -221
  3. package/dist/__tests__/fixture.d.ts.map +1 -1
  4. package/dist/__tests__/fixture.js +33 -11
  5. package/dist/__tests__/fixture.js.map +1 -1
  6. package/dist/adapter-types.d.ts +128 -68
  7. package/dist/adapter-types.d.ts.map +1 -1
  8. package/dist/adapter-types.js +36 -7
  9. package/dist/adapter-types.js.map +1 -1
  10. package/dist/bounded-collections.d.ts.map +1 -1
  11. package/dist/debug-info.d.ts +1 -1
  12. package/dist/debug-info.d.ts.map +1 -1
  13. package/dist/debug-info.js +1 -0
  14. package/dist/debug-info.js.map +1 -1
  15. package/dist/devtools/devtools-messages-client-session.d.ts +389 -0
  16. package/dist/devtools/devtools-messages-client-session.d.ts.map +1 -0
  17. package/dist/devtools/devtools-messages-client-session.js +96 -0
  18. package/dist/devtools/devtools-messages-client-session.js.map +1 -0
  19. package/dist/devtools/devtools-messages-common.d.ts +68 -0
  20. package/dist/devtools/devtools-messages-common.d.ts.map +1 -0
  21. package/dist/devtools/devtools-messages-common.js +60 -0
  22. package/dist/devtools/devtools-messages-common.js.map +1 -0
  23. package/dist/devtools/devtools-messages-leader.d.ts +394 -0
  24. package/dist/devtools/devtools-messages-leader.d.ts.map +1 -0
  25. package/dist/devtools/devtools-messages-leader.js +147 -0
  26. package/dist/devtools/devtools-messages-leader.js.map +1 -0
  27. package/dist/devtools/devtools-messages.d.ts +3 -592
  28. package/dist/devtools/devtools-messages.d.ts.map +1 -1
  29. package/dist/devtools/devtools-messages.js +3 -171
  30. package/dist/devtools/devtools-messages.js.map +1 -1
  31. package/dist/devtools/devtools-sessioninfo.d.ts +28 -0
  32. package/dist/devtools/devtools-sessioninfo.d.ts.map +1 -0
  33. package/dist/devtools/devtools-sessioninfo.js +34 -0
  34. package/dist/devtools/devtools-sessioninfo.js.map +1 -0
  35. package/dist/devtools/mod.d.ts +39 -0
  36. package/dist/devtools/mod.d.ts.map +1 -0
  37. package/dist/devtools/mod.js +27 -0
  38. package/dist/devtools/mod.js.map +1 -0
  39. package/dist/index.d.ts +4 -11
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +4 -7
  42. package/dist/index.js.map +1 -1
  43. package/dist/leader-thread/LeaderSyncProcessor.d.ts +62 -0
  44. package/dist/leader-thread/LeaderSyncProcessor.d.ts.map +1 -0
  45. package/dist/leader-thread/LeaderSyncProcessor.js +589 -0
  46. package/dist/leader-thread/LeaderSyncProcessor.js.map +1 -0
  47. package/dist/leader-thread/apply-event.d.ts +16 -0
  48. package/dist/leader-thread/apply-event.d.ts.map +1 -0
  49. package/dist/leader-thread/apply-event.js +103 -0
  50. package/dist/leader-thread/apply-event.js.map +1 -0
  51. package/dist/leader-thread/connection.d.ts +34 -6
  52. package/dist/leader-thread/connection.d.ts.map +1 -1
  53. package/dist/leader-thread/connection.js +22 -7
  54. package/dist/leader-thread/connection.js.map +1 -1
  55. package/dist/leader-thread/eventlog.d.ts +27 -0
  56. package/dist/leader-thread/eventlog.d.ts.map +1 -0
  57. package/dist/leader-thread/eventlog.js +123 -0
  58. package/dist/leader-thread/eventlog.js.map +1 -0
  59. package/dist/leader-thread/leader-worker-devtools.d.ts +1 -1
  60. package/dist/leader-thread/leader-worker-devtools.d.ts.map +1 -1
  61. package/dist/leader-thread/leader-worker-devtools.js +154 -132
  62. package/dist/leader-thread/leader-worker-devtools.js.map +1 -1
  63. package/dist/leader-thread/make-leader-thread-layer.d.ts +26 -12
  64. package/dist/leader-thread/make-leader-thread-layer.d.ts.map +1 -1
  65. package/dist/leader-thread/make-leader-thread-layer.js +82 -47
  66. package/dist/leader-thread/make-leader-thread-layer.js.map +1 -1
  67. package/dist/leader-thread/mod.d.ts +1 -1
  68. package/dist/leader-thread/mod.d.ts.map +1 -1
  69. package/dist/leader-thread/mod.js +1 -1
  70. package/dist/leader-thread/mod.js.map +1 -1
  71. package/dist/leader-thread/recreate-db.d.ts +4 -2
  72. package/dist/leader-thread/recreate-db.d.ts.map +1 -1
  73. package/dist/leader-thread/recreate-db.js +35 -25
  74. package/dist/leader-thread/recreate-db.js.map +1 -1
  75. package/dist/leader-thread/shutdown-channel.d.ts +2 -5
  76. package/dist/leader-thread/shutdown-channel.d.ts.map +1 -1
  77. package/dist/leader-thread/shutdown-channel.js +2 -4
  78. package/dist/leader-thread/shutdown-channel.js.map +1 -1
  79. package/dist/leader-thread/types.d.ts +86 -39
  80. package/dist/leader-thread/types.d.ts.map +1 -1
  81. package/dist/leader-thread/types.js +1 -3
  82. package/dist/leader-thread/types.js.map +1 -1
  83. package/dist/materializer-helper.d.ts +23 -0
  84. package/dist/materializer-helper.d.ts.map +1 -0
  85. package/dist/materializer-helper.js +70 -0
  86. package/dist/materializer-helper.js.map +1 -0
  87. package/dist/otel.d.ts +2 -0
  88. package/dist/otel.d.ts.map +1 -1
  89. package/dist/otel.js +5 -0
  90. package/dist/otel.js.map +1 -1
  91. package/dist/query-builder/api.d.ts +158 -55
  92. package/dist/query-builder/api.d.ts.map +1 -1
  93. package/dist/query-builder/api.js +3 -5
  94. package/dist/query-builder/api.js.map +1 -1
  95. package/dist/query-builder/astToSql.d.ts +7 -0
  96. package/dist/query-builder/astToSql.d.ts.map +1 -0
  97. package/dist/query-builder/astToSql.js +190 -0
  98. package/dist/query-builder/astToSql.js.map +1 -0
  99. package/dist/query-builder/impl.d.ts +3 -8
  100. package/dist/query-builder/impl.d.ts.map +1 -1
  101. package/dist/query-builder/impl.js +166 -124
  102. package/dist/query-builder/impl.js.map +1 -1
  103. package/dist/query-builder/impl.test.d.ts +86 -1
  104. package/dist/query-builder/impl.test.d.ts.map +1 -1
  105. package/dist/query-builder/impl.test.js +411 -69
  106. package/dist/query-builder/impl.test.js.map +1 -1
  107. package/dist/query-builder/mod.d.ts +7 -0
  108. package/dist/query-builder/mod.d.ts.map +1 -1
  109. package/dist/query-builder/mod.js +7 -0
  110. package/dist/query-builder/mod.js.map +1 -1
  111. package/dist/rehydrate-from-eventlog.d.ts +14 -0
  112. package/dist/rehydrate-from-eventlog.d.ts.map +1 -0
  113. package/dist/rehydrate-from-eventlog.js +65 -0
  114. package/dist/rehydrate-from-eventlog.js.map +1 -0
  115. package/dist/schema/EventDef.d.ts +136 -0
  116. package/dist/schema/EventDef.d.ts.map +1 -0
  117. package/dist/schema/EventDef.js +58 -0
  118. package/dist/schema/EventDef.js.map +1 -0
  119. package/dist/schema/EventId.d.ts +35 -15
  120. package/dist/schema/EventId.d.ts.map +1 -1
  121. package/dist/schema/EventId.js +57 -11
  122. package/dist/schema/EventId.js.map +1 -1
  123. package/dist/schema/EventId.test.d.ts +2 -0
  124. package/dist/schema/EventId.test.d.ts.map +1 -0
  125. package/dist/schema/EventId.test.js +11 -0
  126. package/dist/schema/EventId.test.js.map +1 -0
  127. package/dist/schema/LiveStoreEvent.d.ts +255 -0
  128. package/dist/schema/LiveStoreEvent.d.ts.map +1 -0
  129. package/dist/schema/LiveStoreEvent.js +118 -0
  130. package/dist/schema/LiveStoreEvent.js.map +1 -0
  131. package/dist/schema/client-document-def.d.ts +223 -0
  132. package/dist/schema/client-document-def.d.ts.map +1 -0
  133. package/dist/schema/client-document-def.js +170 -0
  134. package/dist/schema/client-document-def.js.map +1 -0
  135. package/dist/schema/client-document-def.test.d.ts +2 -0
  136. package/dist/schema/client-document-def.test.d.ts.map +1 -0
  137. package/dist/schema/client-document-def.test.js +201 -0
  138. package/dist/schema/client-document-def.test.js.map +1 -0
  139. package/dist/schema/db-schema/ast/sqlite.d.ts +69 -0
  140. package/dist/schema/db-schema/ast/sqlite.d.ts.map +1 -0
  141. package/dist/schema/db-schema/ast/sqlite.js +71 -0
  142. package/dist/schema/db-schema/ast/sqlite.js.map +1 -0
  143. package/dist/schema/db-schema/ast/validate.d.ts +3 -0
  144. package/dist/schema/db-schema/ast/validate.d.ts.map +1 -0
  145. package/dist/schema/db-schema/ast/validate.js +12 -0
  146. package/dist/schema/db-schema/ast/validate.js.map +1 -0
  147. package/dist/schema/db-schema/dsl/field-defs.d.ts +90 -0
  148. package/dist/schema/db-schema/dsl/field-defs.d.ts.map +1 -0
  149. package/dist/schema/db-schema/dsl/field-defs.js +87 -0
  150. package/dist/schema/db-schema/dsl/field-defs.js.map +1 -0
  151. package/dist/schema/db-schema/dsl/field-defs.test.d.ts +2 -0
  152. package/dist/schema/db-schema/dsl/field-defs.test.d.ts.map +1 -0
  153. package/dist/schema/db-schema/dsl/field-defs.test.js +29 -0
  154. package/dist/schema/db-schema/dsl/field-defs.test.js.map +1 -0
  155. package/dist/schema/db-schema/dsl/mod.d.ts +90 -0
  156. package/dist/schema/db-schema/dsl/mod.d.ts.map +1 -0
  157. package/dist/schema/db-schema/dsl/mod.js +41 -0
  158. package/dist/schema/db-schema/dsl/mod.js.map +1 -0
  159. package/dist/schema/db-schema/hash.d.ts +2 -0
  160. package/dist/schema/db-schema/hash.d.ts.map +1 -0
  161. package/dist/schema/db-schema/hash.js +14 -0
  162. package/dist/schema/db-schema/hash.js.map +1 -0
  163. package/dist/schema/db-schema/mod.d.ts +3 -0
  164. package/dist/schema/db-schema/mod.d.ts.map +1 -0
  165. package/dist/schema/db-schema/mod.js +3 -0
  166. package/dist/schema/db-schema/mod.js.map +1 -0
  167. package/dist/schema/events.d.ts +2 -0
  168. package/dist/schema/events.d.ts.map +1 -0
  169. package/dist/schema/events.js +2 -0
  170. package/dist/schema/events.js.map +1 -0
  171. package/dist/schema/mod.d.ts +5 -3
  172. package/dist/schema/mod.d.ts.map +1 -1
  173. package/dist/schema/mod.js +5 -3
  174. package/dist/schema/mod.js.map +1 -1
  175. package/dist/schema/schema-helpers.d.ts.map +1 -1
  176. package/dist/schema/schema-helpers.js +1 -1
  177. package/dist/schema/schema-helpers.js.map +1 -1
  178. package/dist/schema/schema.d.ts +30 -23
  179. package/dist/schema/schema.d.ts.map +1 -1
  180. package/dist/schema/schema.js +48 -35
  181. package/dist/schema/schema.js.map +1 -1
  182. package/dist/schema/sqlite-state.d.ts +12 -0
  183. package/dist/schema/sqlite-state.d.ts.map +1 -0
  184. package/dist/schema/sqlite-state.js +36 -0
  185. package/dist/schema/sqlite-state.js.map +1 -0
  186. package/dist/schema/system-tables.d.ts +179 -125
  187. package/dist/schema/system-tables.d.ts.map +1 -1
  188. package/dist/schema/system-tables.js +76 -41
  189. package/dist/schema/system-tables.js.map +1 -1
  190. package/dist/schema/table-def.d.ts +37 -109
  191. package/dist/schema/table-def.d.ts.map +1 -1
  192. package/dist/schema/table-def.js +23 -66
  193. package/dist/schema/table-def.js.map +1 -1
  194. package/dist/schema/view.d.ts +3 -0
  195. package/dist/schema/view.d.ts.map +1 -0
  196. package/dist/schema/view.js +3 -0
  197. package/dist/schema/view.js.map +1 -0
  198. package/dist/schema-management/common.d.ts +7 -7
  199. package/dist/schema-management/common.d.ts.map +1 -1
  200. package/dist/schema-management/common.js.map +1 -1
  201. package/dist/schema-management/migrations.d.ts +6 -6
  202. package/dist/schema-management/migrations.d.ts.map +1 -1
  203. package/dist/schema-management/migrations.js +19 -14
  204. package/dist/schema-management/migrations.js.map +1 -1
  205. package/dist/schema-management/validate-mutation-defs.d.ts +3 -3
  206. package/dist/schema-management/validate-mutation-defs.d.ts.map +1 -1
  207. package/dist/schema-management/validate-mutation-defs.js +17 -17
  208. package/dist/schema-management/validate-mutation-defs.js.map +1 -1
  209. package/dist/sql-queries/misc.d.ts.map +1 -1
  210. package/dist/sql-queries/sql-queries.d.ts +1 -1
  211. package/dist/sql-queries/sql-queries.d.ts.map +1 -1
  212. package/dist/sql-queries/sql-queries.js.map +1 -1
  213. package/dist/sql-queries/sql-query-builder.d.ts +1 -1
  214. package/dist/sql-queries/sql-query-builder.d.ts.map +1 -1
  215. package/dist/sql-queries/sql-query-builder.js.map +1 -1
  216. package/dist/sql-queries/types.d.ts +2 -1
  217. package/dist/sql-queries/types.d.ts.map +1 -1
  218. package/dist/sql-queries/types.js.map +1 -1
  219. package/dist/sync/ClientSessionSyncProcessor.d.ts +66 -0
  220. package/dist/sync/ClientSessionSyncProcessor.d.ts.map +1 -0
  221. package/dist/sync/ClientSessionSyncProcessor.js +209 -0
  222. package/dist/sync/ClientSessionSyncProcessor.js.map +1 -0
  223. package/dist/sync/index.d.ts +1 -1
  224. package/dist/sync/index.d.ts.map +1 -1
  225. package/dist/sync/index.js +1 -1
  226. package/dist/sync/index.js.map +1 -1
  227. package/dist/sync/next/compact-events.d.ts.map +1 -1
  228. package/dist/sync/next/facts.d.ts +19 -19
  229. package/dist/sync/next/facts.d.ts.map +1 -1
  230. package/dist/sync/next/facts.js +3 -3
  231. package/dist/sync/next/facts.js.map +1 -1
  232. package/dist/sync/next/history-dag-common.d.ts +6 -7
  233. package/dist/sync/next/history-dag-common.d.ts.map +1 -1
  234. package/dist/sync/next/history-dag-common.js +4 -2
  235. package/dist/sync/next/history-dag-common.js.map +1 -1
  236. package/dist/sync/next/history-dag.d.ts.map +1 -1
  237. package/dist/sync/next/history-dag.js +2 -2
  238. package/dist/sync/next/history-dag.js.map +1 -1
  239. package/dist/sync/next/rebase-events.d.ts +10 -8
  240. package/dist/sync/next/rebase-events.d.ts.map +1 -1
  241. package/dist/sync/next/rebase-events.js +11 -8
  242. package/dist/sync/next/rebase-events.js.map +1 -1
  243. package/dist/sync/next/test/compact-events.calculator.test.js +38 -33
  244. package/dist/sync/next/test/compact-events.calculator.test.js.map +1 -1
  245. package/dist/sync/next/test/compact-events.test.js +76 -76
  246. package/dist/sync/next/test/compact-events.test.js.map +1 -1
  247. package/dist/sync/next/test/{mutation-fixtures.d.ts → event-fixtures.d.ts} +29 -29
  248. package/dist/sync/next/test/event-fixtures.d.ts.map +1 -0
  249. package/dist/sync/next/test/{mutation-fixtures.js → event-fixtures.js} +67 -36
  250. package/dist/sync/next/test/event-fixtures.js.map +1 -0
  251. package/dist/sync/next/test/mod.d.ts +1 -1
  252. package/dist/sync/next/test/mod.d.ts.map +1 -1
  253. package/dist/sync/next/test/mod.js +1 -1
  254. package/dist/sync/next/test/mod.js.map +1 -1
  255. package/dist/sync/sync.d.ts +55 -20
  256. package/dist/sync/sync.d.ts.map +1 -1
  257. package/dist/sync/sync.js +7 -3
  258. package/dist/sync/sync.js.map +1 -1
  259. package/dist/sync/syncstate.d.ts +213 -82
  260. package/dist/sync/syncstate.d.ts.map +1 -1
  261. package/dist/sync/syncstate.js +319 -120
  262. package/dist/sync/syncstate.js.map +1 -1
  263. package/dist/sync/syncstate.test.js +295 -275
  264. package/dist/sync/syncstate.test.js.map +1 -1
  265. package/dist/sync/validate-push-payload.d.ts +2 -2
  266. package/dist/sync/validate-push-payload.d.ts.map +1 -1
  267. package/dist/sync/validate-push-payload.js +2 -2
  268. package/dist/sync/validate-push-payload.js.map +1 -1
  269. package/dist/util.d.ts +2 -2
  270. package/dist/util.d.ts.map +1 -1
  271. package/dist/version.d.ts +1 -1
  272. package/dist/version.d.ts.map +1 -1
  273. package/dist/version.js +1 -1
  274. package/dist/version.js.map +1 -1
  275. package/package.json +6 -6
  276. package/src/__tests__/fixture.ts +36 -15
  277. package/src/adapter-types.ts +111 -74
  278. package/src/debug-info.ts +1 -0
  279. package/src/devtools/devtools-messages-client-session.ts +141 -0
  280. package/src/devtools/devtools-messages-common.ts +115 -0
  281. package/src/devtools/devtools-messages-leader.ts +191 -0
  282. package/src/devtools/devtools-messages.ts +3 -243
  283. package/src/devtools/devtools-sessioninfo.ts +99 -0
  284. package/src/devtools/mod.ts +36 -0
  285. package/src/index.ts +4 -13
  286. package/src/leader-thread/LeaderSyncProcessor.ts +935 -0
  287. package/src/leader-thread/apply-event.ts +173 -0
  288. package/src/leader-thread/connection.ts +54 -9
  289. package/src/leader-thread/eventlog.ts +199 -0
  290. package/src/leader-thread/leader-worker-devtools.ts +212 -189
  291. package/src/leader-thread/make-leader-thread-layer.ts +143 -77
  292. package/src/leader-thread/mod.ts +1 -1
  293. package/src/leader-thread/recreate-db.ts +41 -30
  294. package/src/leader-thread/shutdown-channel.ts +2 -4
  295. package/src/leader-thread/types.ts +95 -51
  296. package/src/materializer-helper.ts +110 -0
  297. package/src/otel.ts +8 -0
  298. package/src/query-builder/api.ts +236 -85
  299. package/src/query-builder/astToSql.ts +232 -0
  300. package/src/query-builder/impl.test.ts +447 -78
  301. package/src/query-builder/impl.ts +209 -144
  302. package/src/query-builder/mod.ts +7 -0
  303. package/src/rehydrate-from-eventlog.ts +114 -0
  304. package/src/schema/EventDef.ts +216 -0
  305. package/src/schema/EventId.test.ts +12 -0
  306. package/src/schema/EventId.ts +75 -15
  307. package/src/schema/LiveStoreEvent.ts +239 -0
  308. package/src/schema/client-document-def.test.ts +239 -0
  309. package/src/schema/client-document-def.ts +444 -0
  310. package/src/schema/db-schema/ast/sqlite.ts +142 -0
  311. package/src/schema/db-schema/ast/validate.ts +13 -0
  312. package/src/schema/db-schema/dsl/__snapshots__/field-defs.test.ts.snap +206 -0
  313. package/src/schema/db-schema/dsl/field-defs.test.ts +35 -0
  314. package/src/schema/db-schema/dsl/field-defs.ts +242 -0
  315. package/src/schema/db-schema/dsl/mod.ts +222 -0
  316. package/src/schema/db-schema/hash.ts +14 -0
  317. package/src/schema/db-schema/mod.ts +2 -0
  318. package/src/schema/events.ts +1 -0
  319. package/src/schema/mod.ts +5 -3
  320. package/src/schema/schema-helpers.ts +1 -1
  321. package/src/schema/schema.ts +84 -62
  322. package/src/schema/sqlite-state.ts +62 -0
  323. package/src/schema/system-tables.ts +68 -50
  324. package/src/schema/table-def.ts +68 -214
  325. package/src/schema/view.ts +2 -0
  326. package/src/schema-management/common.ts +7 -7
  327. package/src/schema-management/migrations.ts +27 -24
  328. package/src/schema-management/validate-mutation-defs.ts +22 -24
  329. package/src/sql-queries/sql-queries.ts +1 -1
  330. package/src/sql-queries/sql-query-builder.ts +1 -2
  331. package/src/sql-queries/types.ts +3 -1
  332. package/src/sync/ClientSessionSyncProcessor.ts +332 -0
  333. package/src/sync/index.ts +1 -1
  334. package/src/sync/next/facts.ts +32 -33
  335. package/src/sync/next/history-dag-common.ts +9 -5
  336. package/src/sync/next/history-dag.ts +2 -2
  337. package/src/sync/next/rebase-events.ts +22 -16
  338. package/src/sync/next/test/compact-events.calculator.test.ts +45 -45
  339. package/src/sync/next/test/compact-events.test.ts +78 -78
  340. package/src/sync/next/test/event-fixtures.ts +219 -0
  341. package/src/sync/next/test/mod.ts +1 -1
  342. package/src/sync/sync.ts +51 -19
  343. package/src/sync/syncstate.test.ts +335 -308
  344. package/src/sync/syncstate.ts +394 -212
  345. package/src/sync/validate-push-payload.ts +7 -4
  346. package/src/version.ts +1 -1
  347. package/tmp/pack.tgz +0 -0
  348. package/tsconfig.json +2 -1
  349. package/dist/derived-mutations.d.ts +0 -109
  350. package/dist/derived-mutations.d.ts.map +0 -1
  351. package/dist/derived-mutations.js +0 -54
  352. package/dist/derived-mutations.js.map +0 -1
  353. package/dist/derived-mutations.test.d.ts +0 -2
  354. package/dist/derived-mutations.test.d.ts.map +0 -1
  355. package/dist/derived-mutations.test.js +0 -93
  356. package/dist/derived-mutations.test.js.map +0 -1
  357. package/dist/devtools/devtools-bridge.d.ts +0 -12
  358. package/dist/devtools/devtools-bridge.d.ts.map +0 -1
  359. package/dist/devtools/devtools-bridge.js +0 -2
  360. package/dist/devtools/devtools-bridge.js.map +0 -1
  361. package/dist/devtools/index.d.ts +0 -42
  362. package/dist/devtools/index.d.ts.map +0 -1
  363. package/dist/devtools/index.js +0 -48
  364. package/dist/devtools/index.js.map +0 -1
  365. package/dist/init-singleton-tables.d.ts +0 -4
  366. package/dist/init-singleton-tables.d.ts.map +0 -1
  367. package/dist/init-singleton-tables.js +0 -16
  368. package/dist/init-singleton-tables.js.map +0 -1
  369. package/dist/leader-thread/apply-mutation.d.ts +0 -8
  370. package/dist/leader-thread/apply-mutation.d.ts.map +0 -1
  371. package/dist/leader-thread/apply-mutation.js +0 -95
  372. package/dist/leader-thread/apply-mutation.js.map +0 -1
  373. package/dist/leader-thread/leader-sync-processor.d.ts +0 -47
  374. package/dist/leader-thread/leader-sync-processor.d.ts.map +0 -1
  375. package/dist/leader-thread/leader-sync-processor.js +0 -422
  376. package/dist/leader-thread/leader-sync-processor.js.map +0 -1
  377. package/dist/leader-thread/mutationlog.d.ts +0 -23
  378. package/dist/leader-thread/mutationlog.d.ts.map +0 -1
  379. package/dist/leader-thread/mutationlog.js +0 -27
  380. package/dist/leader-thread/mutationlog.js.map +0 -1
  381. package/dist/leader-thread/pull-queue-set.d.ts +0 -7
  382. package/dist/leader-thread/pull-queue-set.d.ts.map +0 -1
  383. package/dist/leader-thread/pull-queue-set.js +0 -39
  384. package/dist/leader-thread/pull-queue-set.js.map +0 -1
  385. package/dist/mutation.d.ts +0 -13
  386. package/dist/mutation.d.ts.map +0 -1
  387. package/dist/mutation.js +0 -57
  388. package/dist/mutation.js.map +0 -1
  389. package/dist/query-info.d.ts +0 -38
  390. package/dist/query-info.d.ts.map +0 -1
  391. package/dist/query-info.js +0 -7
  392. package/dist/query-info.js.map +0 -1
  393. package/dist/rehydrate-from-mutationlog.d.ts +0 -14
  394. package/dist/rehydrate-from-mutationlog.d.ts.map +0 -1
  395. package/dist/rehydrate-from-mutationlog.js +0 -72
  396. package/dist/rehydrate-from-mutationlog.js.map +0 -1
  397. package/dist/schema/MutationEvent.d.ts +0 -191
  398. package/dist/schema/MutationEvent.d.ts.map +0 -1
  399. package/dist/schema/MutationEvent.js +0 -56
  400. package/dist/schema/MutationEvent.js.map +0 -1
  401. package/dist/schema/mutations.d.ts +0 -107
  402. package/dist/schema/mutations.d.ts.map +0 -1
  403. package/dist/schema/mutations.js +0 -42
  404. package/dist/schema/mutations.js.map +0 -1
  405. package/dist/sync/client-session-sync-processor.d.ts +0 -45
  406. package/dist/sync/client-session-sync-processor.d.ts.map +0 -1
  407. package/dist/sync/client-session-sync-processor.js +0 -131
  408. package/dist/sync/client-session-sync-processor.js.map +0 -1
  409. package/dist/sync/next/test/mutation-fixtures.d.ts.map +0 -1
  410. package/dist/sync/next/test/mutation-fixtures.js.map +0 -1
  411. package/src/derived-mutations.test.ts +0 -101
  412. package/src/derived-mutations.ts +0 -166
  413. package/src/devtools/devtools-bridge.ts +0 -13
  414. package/src/devtools/index.ts +0 -48
  415. package/src/init-singleton-tables.ts +0 -24
  416. package/src/leader-thread/apply-mutation.ts +0 -143
  417. package/src/leader-thread/leader-sync-processor.ts +0 -666
  418. package/src/leader-thread/mutationlog.ts +0 -42
  419. package/src/leader-thread/pull-queue-set.ts +0 -58
  420. package/src/mutation.ts +0 -81
  421. package/src/query-info.ts +0 -78
  422. package/src/rehydrate-from-mutationlog.ts +0 -127
  423. package/src/schema/MutationEvent.ts +0 -161
  424. package/src/schema/mutations.ts +0 -192
  425. package/src/sync/client-session-sync-processor.ts +0 -207
  426. package/src/sync/next/test/mutation-fixtures.ts +0 -231
@@ -2,22 +2,23 @@
2
2
  import { describe, expect, it } from 'vitest'
3
3
 
4
4
  import * as EventId from '../schema/EventId.js'
5
- import * as MutationEvent from '../schema/MutationEvent.js'
5
+ import * as LiveStoreEvent from '../schema/LiveStoreEvent.js'
6
6
  import * as SyncState from './syncstate.js'
7
7
 
8
- class TestEvent extends MutationEvent.EncodedWithMeta {
8
+ class TestEvent extends LiveStoreEvent.EncodedWithMeta {
9
9
  constructor(
10
- public readonly id: EventId.EventId,
11
- public readonly parentId: EventId.EventId,
10
+ id: EventId.EventId | typeof EventId.EventId.Encoded,
11
+ parentId: EventId.EventId,
12
12
  public readonly payload: string,
13
13
  public readonly isLocal: boolean,
14
14
  ) {
15
15
  super({
16
- id,
17
- parentId,
18
- mutation: 'a',
16
+ id: EventId.make(id),
17
+ parentId: EventId.make(parentId),
18
+ name: 'a',
19
19
  args: payload,
20
- meta: {},
20
+ clientId: 'static-local-id',
21
+ sessionId: 'static-session-id',
21
22
  })
22
23
  }
23
24
 
@@ -26,411 +27,431 @@ class TestEvent extends MutationEvent.EncodedWithMeta {
26
27
  }
27
28
 
28
29
  // Only used for Vitest printing
29
- // toJSON = () => `(${this.id.global},${this.id.local},${this.payload})`
30
+ // toJSON = () => `(${this.id.global},${this.id.client},${this.payload})`
30
31
  // toString = () => this.toJSON()
31
32
  }
32
33
 
33
- const e_r_1 = new TestEvent({ global: -1, local: 1 }, EventId.ROOT, 'a', true)
34
- const e_0_0 = new TestEvent({ global: 0, local: 0 }, EventId.ROOT, 'a', false)
35
- const e_0_1 = new TestEvent({ global: 0, local: 1 }, e_0_0.id, 'a', true)
36
- const e_0_2 = new TestEvent({ global: 0, local: 2 }, e_0_1.id, 'a', true)
37
- const e_0_3 = new TestEvent({ global: 0, local: 3 }, e_0_2.id, 'a', true)
38
- const e_1_0 = new TestEvent({ global: 1, local: 0 }, e_0_0.id, 'a', false)
39
- const e_1_1 = new TestEvent({ global: 1, local: 1 }, e_1_0.id, 'a', true)
34
+ const e0_1 = new TestEvent({ global: 0, client: 1 }, EventId.ROOT, 'a', true)
35
+ const e1_0 = new TestEvent({ global: 1, client: 0 }, EventId.ROOT, 'a', false)
36
+ const e1_1 = new TestEvent({ global: 1, client: 1 }, e1_0.id, 'a', true)
37
+ const e1_2 = new TestEvent({ global: 1, client: 2 }, e1_1.id, 'a', true)
38
+ const e1_3 = new TestEvent({ global: 1, client: 3 }, e1_2.id, 'a', true)
39
+ const e2_0 = new TestEvent({ global: 2, client: 0 }, e1_0.id, 'a', false)
40
+ const e2_1 = new TestEvent({ global: 2, client: 1 }, e2_0.id, 'a', true)
40
41
 
41
- const isEqualEvent = MutationEvent.isEqualEncoded
42
+ const isEqualEvent = LiveStoreEvent.isEqualEncoded
42
43
 
43
- const isLocalEvent = (event: MutationEvent.EncodedWithMeta) => (event as TestEvent).isLocal
44
+ const isClientEvent = (event: LiveStoreEvent.EncodedWithMeta) => (event as TestEvent).isLocal
44
45
 
45
46
  describe('syncstate', () => {
46
- describe('updateSyncState', () => {
47
- const run = ({
47
+ describe('merge', () => {
48
+ const merge = ({
48
49
  syncState,
49
50
  payload,
50
- ignoreLocalEvents = false,
51
+ ignoreClientEvents = false,
51
52
  }: {
52
53
  syncState: SyncState.SyncState
53
54
  payload: typeof SyncState.Payload.Type
54
- ignoreLocalEvents?: boolean
55
- }) => SyncState.updateSyncState({ syncState, payload, isLocalEvent, isEqualEvent, ignoreLocalEvents })
56
-
57
- describe.each([{ trimRollbackUntil: false }, { trimRollbackUntil: true }])(
58
- 'upstream-rebase (trimRollbackUntil: $trimRollbackUntil)',
59
- ({ trimRollbackUntil }) => {
60
- it('should rollback until start', () => {
61
- const syncState = {
62
- pending: [e_1_0],
63
- rollbackTail: [e_0_0, e_0_1],
64
- upstreamHead: EventId.ROOT,
65
- localHead: e_1_0.id,
66
- }
67
- const e_0_0_e_1_0 = e_0_0.rebase_(e_1_0.id)
68
- const e_0_1_e_1_1 = e_0_1.rebase_(e_0_0_e_1_0.id)
69
- const result = run({
70
- syncState,
71
- payload: {
72
- _tag: 'upstream-rebase',
73
- rollbackUntil: e_0_0.id,
74
- newEvents: [e_0_0_e_1_0, e_0_1_e_1_1],
75
- trimRollbackUntil: trimRollbackUntil ? e_0_1_e_1_1.id : undefined,
76
- },
77
- })
78
- const e_1_0_e_2_0 = e_1_0.rebase_(e_0_0_e_1_0.id)
79
- expectRebase(result)
80
- expectEventArraysEqual(result.newSyncState.pending, [e_1_0_e_2_0])
81
- if (trimRollbackUntil) {
82
- expectEventArraysEqual(result.newSyncState.rollbackTail, [])
83
- } else {
84
- expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_0_e_1_0, e_0_1_e_1_1])
85
- }
86
- expect(result.newSyncState.upstreamHead).toBe(e_0_1_e_1_1.id)
87
- expect(result.newSyncState.localHead).toMatchObject(e_1_0_e_2_0.id)
88
- expectEventArraysEqual(result.newEvents, [e_0_0_e_1_0, e_0_1_e_1_1])
89
- expectEventArraysEqual(result.eventsToRollback, [e_0_0, e_0_1, e_1_0])
90
- })
91
-
92
- it('should rollback only to specified point', () => {
93
- const syncState = {
94
- pending: [e_1_0],
95
- rollbackTail: [e_0_0, e_0_1],
96
- upstreamHead: EventId.ROOT,
97
- localHead: e_1_0.id,
98
- }
99
- const e_0_1_e_1_0 = e_0_1.rebase_(e_0_0.id)
100
- const result = run({
101
- syncState,
102
- payload: {
103
- _tag: 'upstream-rebase',
104
- rollbackUntil: e_0_1.id,
105
- newEvents: [e_0_1_e_1_0],
106
- trimRollbackUntil: trimRollbackUntil ? e_0_0.id : undefined,
107
- },
108
- })
109
- const e_1_0_e_2_0 = e_1_0.rebase_(e_0_1_e_1_0.id)
110
- expectRebase(result)
111
- expectEventArraysEqual(result.newSyncState.pending, [e_1_0_e_2_0])
112
- if (trimRollbackUntil) {
113
- expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_1_e_1_0])
114
- } else {
115
- expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_0, e_0_1_e_1_0])
116
- }
117
- expect(result.newSyncState.upstreamHead).toBe(e_0_1_e_1_0.id)
118
- expect(result.newSyncState.localHead).toMatchObject(e_1_0_e_2_0.id)
119
- expectEventArraysEqual(result.newEvents, [e_0_1_e_1_0])
120
- expectEventArraysEqual(result.eventsToRollback, [e_0_1, e_1_0])
121
- })
122
-
123
- it('should work for empty pending', () => {
124
- const syncState = { pending: [], rollbackTail: [e_0_0], upstreamHead: EventId.ROOT, localHead: e_0_0.id }
125
- const result = run({
126
- syncState,
127
- payload: { _tag: 'upstream-rebase', rollbackUntil: e_0_0.id, newEvents: [e_1_0] },
128
- })
129
- expectRebase(result)
130
- expectEventArraysEqual(result.newSyncState.pending, [])
131
- expectEventArraysEqual(result.newSyncState.rollbackTail, [e_1_0])
132
- expect(result.newSyncState.upstreamHead).toBe(e_1_0.id)
133
- expect(result.newSyncState.localHead).toMatchObject(e_1_0.id)
134
- expect(result.newEvents).toEqual([e_1_0])
135
- })
136
-
137
- it('should fail for empty rollback tail', () => {
138
- const syncState = { pending: [], rollbackTail: [], upstreamHead: EventId.ROOT, localHead: e_0_0.id }
139
- expect(() =>
140
- run({
141
- syncState,
142
- payload: { _tag: 'upstream-rebase', rollbackUntil: e_0_0.id, newEvents: [e_1_0] },
143
- }),
144
- ).toThrow()
55
+ ignoreClientEvents?: boolean
56
+ }) => SyncState.merge({ syncState, payload, isClientEvent, isEqualEvent, ignoreClientEvents })
57
+
58
+ describe('upstream-rebase', () => {
59
+ it('should rollback until start', () => {
60
+ const syncState = new SyncState.SyncState({
61
+ pending: [e2_0],
62
+ upstreamHead: EventId.ROOT,
63
+ localHead: e2_0.id,
64
+ })
65
+ const e1_0_e2_0 = e1_0.rebase_(e2_0.id)
66
+ const e1_1_e2_1 = e1_1.rebase_(e1_0_e2_0.id)
67
+ const result = merge({
68
+ syncState,
69
+ payload: SyncState.PayloadUpstreamRebase.make({
70
+ rollbackEvents: [e1_0, e1_1],
71
+ newEvents: [e1_0_e2_0, e1_1_e2_1],
72
+ }),
145
73
  })
74
+ const e2_0_e3_0 = e2_0.rebase_(e1_0_e2_0.id)
75
+ expectRebase(result)
76
+ expectEventArraysEqual(result.newSyncState.pending, [e2_0_e3_0])
77
+ expect(result.newSyncState.upstreamHead).toMatchObject(e1_1_e2_1.id)
78
+ expect(result.newSyncState.localHead).toMatchObject(e2_0_e3_0.id)
79
+ expectEventArraysEqual(result.newEvents, [e1_0_e2_0, e1_1_e2_1, e2_0_e3_0])
80
+ expectEventArraysEqual(result.rollbackEvents, [e1_0, e1_1, e2_0])
81
+ })
146
82
 
147
- it('should work for empty incoming', () => {
148
- const syncState = { pending: [], rollbackTail: [e_0_0], upstreamHead: EventId.ROOT, localHead: e_0_0.id }
149
- const result = run({
150
- syncState,
151
- payload: { _tag: 'upstream-rebase', rollbackUntil: e_0_0.id, newEvents: [] },
152
- })
153
- expectRebase(result)
154
- expectEventArraysEqual(result.newSyncState.pending, [])
155
- expectEventArraysEqual(result.newSyncState.rollbackTail, [])
156
- expect(result.newSyncState.upstreamHead).toBe(EventId.ROOT)
157
- expect(result.newSyncState.localHead).toMatchObject(EventId.ROOT)
158
- expect(result.newEvents).toEqual([])
83
+ it('should rollback only to specified point', () => {
84
+ const syncState = new SyncState.SyncState({
85
+ pending: [e2_0],
86
+ upstreamHead: EventId.ROOT,
87
+ localHead: e2_0.id,
88
+ })
89
+ const e1_1_e2_0 = e1_1.rebase_(e1_0.id)
90
+ const result = merge({
91
+ syncState,
92
+ payload: SyncState.PayloadUpstreamRebase.make({
93
+ newEvents: [e1_1_e2_0],
94
+ rollbackEvents: [e1_1],
95
+ }),
159
96
  })
160
- },
161
- )
97
+ const e2_0_e3_0 = e2_0.rebase_(e1_1_e2_0.id)
98
+ expectRebase(result)
99
+ expectEventArraysEqual(result.newSyncState.pending, [e2_0_e3_0])
100
+ expect(result.newSyncState.upstreamHead).toMatchObject(e1_1_e2_0.id)
101
+ expect(result.newSyncState.localHead).toMatchObject(e2_0_e3_0.id)
102
+ expectEventArraysEqual(result.newEvents, [e1_1_e2_0, e2_0_e3_0])
103
+ expectEventArraysEqual(result.rollbackEvents, [e1_1, e2_0])
104
+ })
105
+
106
+ it('should work for empty pending', () => {
107
+ const syncState = new SyncState.SyncState({
108
+ pending: [],
109
+ upstreamHead: EventId.ROOT,
110
+ localHead: e1_0.id,
111
+ })
112
+ const result = merge({
113
+ syncState,
114
+ payload: SyncState.PayloadUpstreamRebase.make({ rollbackEvents: [e1_0], newEvents: [e2_0] }),
115
+ })
116
+ expectRebase(result)
117
+ expectEventArraysEqual(result.newSyncState.pending, [])
118
+ expect(result.newSyncState.upstreamHead).toMatchObject(e2_0.id)
119
+ expect(result.newSyncState.localHead).toMatchObject(e2_0.id)
120
+ expect(result.newEvents).toStrictEqual([e2_0])
121
+ })
122
+ })
162
123
 
163
124
  describe('upstream-advance: advance', () => {
164
- it('should throw error if newEvents are not sorted in ascending order by eventId (local)', () => {
165
- const syncState = { pending: [e_0_0], rollbackTail: [], upstreamHead: EventId.ROOT, localHead: e_0_0.id }
166
- expect(() => run({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_1, e_0_0] } })).toThrow()
125
+ it('should throw error if newEvents are not sorted in ascending order by eventId (client)', () => {
126
+ const syncState = new SyncState.SyncState({
127
+ pending: [e1_0],
128
+ upstreamHead: EventId.ROOT,
129
+ localHead: e1_0.id,
130
+ })
131
+ const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e1_1, e1_0] } })
132
+ expect(result).toMatchObject({ _tag: 'unexpected-error' })
167
133
  })
168
134
 
169
135
  it('should throw error if newEvents are not sorted in ascending order by eventId (global)', () => {
170
- const syncState = { pending: [e_0_0], rollbackTail: [], upstreamHead: EventId.ROOT, localHead: e_0_0.id }
171
- expect(() => run({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_1_0, e_0_0] } })).toThrow()
136
+ const syncState = new SyncState.SyncState({
137
+ pending: [e1_0],
138
+ upstreamHead: EventId.ROOT,
139
+ localHead: e1_0.id,
140
+ })
141
+ const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e2_0, e1_0] } })
142
+ expect(result).toMatchObject({ _tag: 'unexpected-error' })
143
+ })
144
+
145
+ it('should throw error if incoming event is < expected upstream head', () => {
146
+ const syncState = new SyncState.SyncState({
147
+ pending: [],
148
+ upstreamHead: e2_0.id,
149
+ localHead: e2_0.id,
150
+ })
151
+ const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e1_0] } })
152
+ expect(result).toMatchObject({ _tag: 'unexpected-error' })
153
+ })
154
+
155
+ it('should throw error if incoming event is = expected upstream head', () => {
156
+ const syncState = new SyncState.SyncState({
157
+ pending: [],
158
+ upstreamHead: e2_0.id,
159
+ localHead: e2_0.id,
160
+ })
161
+ const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e2_0] } })
162
+ expect(result).toMatchObject({ _tag: 'unexpected-error' })
172
163
  })
173
164
 
174
- it('should acknowledge pending event when receiving matching event', () => {
175
- const syncState = { pending: [e_0_0], rollbackTail: [], upstreamHead: EventId.ROOT, localHead: e_0_0.id }
176
- const result = run({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_0] } })
165
+ it('should confirm pending event when receiving matching event', () => {
166
+ const syncState = new SyncState.SyncState({
167
+ pending: [e1_0],
168
+ upstreamHead: EventId.ROOT,
169
+ localHead: e1_0.id,
170
+ })
171
+ const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e1_0] } })
177
172
 
178
173
  expectAdvance(result)
179
174
  expectEventArraysEqual(result.newSyncState.pending, [])
180
- expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_0])
181
- expect(result.newSyncState.upstreamHead).toBe(e_0_0.id)
182
- expect(result.newSyncState.localHead).toMatchObject(e_0_0.id)
183
- expect(result.newEvents).toEqual([])
175
+ expect(result.newSyncState.upstreamHead).toMatchObject(e1_0.id)
176
+ expect(result.newSyncState.localHead).toMatchObject(e1_0.id)
177
+ expectEventArraysEqual(result.newEvents, [])
178
+ expectEventArraysEqual(result.confirmedEvents, [e1_0])
184
179
  })
185
180
 
186
- it('should acknowledge partial pending event when receiving matching event', () => {
187
- const syncState = {
188
- pending: [e_0_0, e_1_0],
189
- rollbackTail: [],
181
+ it('should confirm partial pending event when receiving matching event', () => {
182
+ const syncState = new SyncState.SyncState({
183
+ pending: [e1_0, e2_0],
190
184
  upstreamHead: EventId.ROOT,
191
- localHead: e_1_0.id,
192
- }
193
- const result = run({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_0] } })
185
+ localHead: e2_0.id,
186
+ })
187
+ const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e1_0] } })
194
188
 
195
189
  expectAdvance(result)
196
- expectEventArraysEqual(result.newSyncState.pending, [e_1_0])
197
- expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_0])
198
- expect(result.newSyncState.upstreamHead).toBe(e_0_0.id)
199
- expect(result.newSyncState.localHead).toMatchObject(e_1_0.id)
200
- expect(result.newEvents).toEqual([])
190
+ expectEventArraysEqual(result.newSyncState.pending, [e2_0])
191
+ expect(result.newSyncState.upstreamHead).toMatchObject(e1_0.id)
192
+ expect(result.newSyncState.localHead).toMatchObject(e2_0.id)
193
+ expectEventArraysEqual(result.newEvents, [])
194
+ expectEventArraysEqual(result.confirmedEvents, [e1_0])
201
195
  })
202
196
 
203
- it('should acknowledge pending event and add new event', () => {
204
- const syncState = { pending: [e_0_0], rollbackTail: [], upstreamHead: EventId.ROOT, localHead: e_0_0.id }
205
- const result = run({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_0, e_0_1] } })
197
+ it('should confirm pending event and add new event', () => {
198
+ const syncState = new SyncState.SyncState({
199
+ pending: [e1_0],
200
+ upstreamHead: EventId.ROOT,
201
+ localHead: e1_0.id,
202
+ })
203
+ const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e1_0, e1_1] } })
206
204
 
207
205
  expectAdvance(result)
208
206
  expectEventArraysEqual(result.newSyncState.pending, [])
209
- expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_0, e_0_1])
210
- expect(result.newSyncState.upstreamHead).toBe(e_0_1.id)
211
- expect(result.newSyncState.localHead).toMatchObject(e_0_1.id)
212
- expect(result.newEvents).toEqual([e_0_1])
207
+ expect(result.newSyncState.upstreamHead).toMatchObject(e1_1.id)
208
+ expect(result.newSyncState.localHead).toMatchObject(e1_1.id)
209
+ expect(result.newEvents).toStrictEqual([e1_1])
210
+ expectEventArraysEqual(result.confirmedEvents, [e1_0])
213
211
  })
214
212
 
215
- it('should acknowledge pending event and add multiple new events', () => {
216
- const syncState = { pending: [e_0_1], rollbackTail: [], upstreamHead: e_0_0.id, localHead: e_0_1.id }
217
- const result = run({
213
+ it('should confirm pending event and add multiple new events', () => {
214
+ const syncState = new SyncState.SyncState({
215
+ pending: [e1_1],
216
+ upstreamHead: e1_0.id,
217
+ localHead: e1_1.id,
218
+ })
219
+ const result = merge({
218
220
  syncState,
219
- payload: { _tag: 'upstream-advance', newEvents: [e_0_1, e_0_2, e_0_3, e_1_0, e_1_1] },
221
+ payload: { _tag: 'upstream-advance', newEvents: [e1_1, e1_2, e1_3, e2_0, e2_1] },
220
222
  })
221
223
 
222
224
  expectAdvance(result)
223
225
  expectEventArraysEqual(result.newSyncState.pending, [])
224
- expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_1, e_0_2, e_0_3, e_1_0, e_1_1])
225
- expect(result.newSyncState.upstreamHead).toBe(e_1_1.id)
226
- expect(result.newSyncState.localHead).toMatchObject(e_1_1.id)
227
- expect(result.newEvents).toEqual([e_0_2, e_0_3, e_1_0, e_1_1])
226
+ expect(result.newSyncState.upstreamHead).toMatchObject(e2_1.id)
227
+ expect(result.newSyncState.localHead).toMatchObject(e2_1.id)
228
+ expect(result.newEvents).toStrictEqual([e1_2, e1_3, e2_0, e2_1])
229
+ expectEventArraysEqual(result.confirmedEvents, [e1_1])
230
+ })
231
+
232
+ it('should confirm pending global event while keep pending client events', () => {
233
+ const syncState = new SyncState.SyncState({
234
+ pending: [e1_0, e1_1],
235
+ upstreamHead: EventId.ROOT,
236
+ localHead: e1_1.id,
237
+ })
238
+ const result = merge({
239
+ syncState,
240
+ payload: { _tag: 'upstream-advance', newEvents: [e1_0] },
241
+ })
242
+
243
+ expectAdvance(result)
244
+ expectEventArraysEqual(result.newSyncState.pending, [e1_1])
245
+ expect(result.newSyncState.upstreamHead).toMatchObject(e1_0.id)
246
+ expect(result.newSyncState.localHead).toMatchObject(e1_1.id)
247
+ expectEventArraysEqual(result.newEvents, [])
248
+ expectEventArraysEqual(result.confirmedEvents, [e1_0])
228
249
  })
229
250
 
230
- it('should ignore local events (incoming is subset of pending)', () => {
231
- const syncState = {
232
- pending: [e_r_1, e_0_0],
233
- rollbackTail: [],
251
+ it('should ignore client events (incoming is subset of pending)', () => {
252
+ const syncState = new SyncState.SyncState({
253
+ pending: [e0_1, e1_0],
234
254
  upstreamHead: EventId.ROOT,
235
- localHead: e_0_0.id,
236
- }
237
- const result = run({
255
+ localHead: e1_0.id,
256
+ })
257
+ const result = merge({
238
258
  syncState,
239
- payload: { _tag: 'upstream-advance', newEvents: [e_0_0] },
240
- ignoreLocalEvents: true,
259
+ payload: { _tag: 'upstream-advance', newEvents: [e1_0] },
260
+ ignoreClientEvents: true,
241
261
  })
242
262
  expectAdvance(result)
243
263
  expectEventArraysEqual(result.newSyncState.pending, [])
244
- expectEventArraysEqual(result.newSyncState.rollbackTail, [e_r_1, e_0_0])
245
- expect(result.newSyncState.upstreamHead).toBe(e_0_0.id)
246
- expect(result.newSyncState.localHead).toMatchObject(e_0_0.id)
247
- expect(result.newEvents).toEqual([])
264
+ expect(result.newSyncState.upstreamHead).toMatchObject(e1_0.id)
265
+ expect(result.newSyncState.localHead).toMatchObject(e1_0.id)
266
+ expectEventArraysEqual(result.newEvents, [])
267
+ expectEventArraysEqual(result.confirmedEvents, [e0_1, e1_0])
248
268
  })
249
269
 
250
- it('should ignore local events (incoming is subset of pending case 2)', () => {
251
- const syncState = {
252
- pending: [e_r_1, e_0_0, e_1_0],
253
- rollbackTail: [],
270
+ it('should ignore client events (incoming is subset of pending case 2)', () => {
271
+ const syncState = new SyncState.SyncState({
272
+ pending: [e0_1, e1_0, e2_0],
254
273
  upstreamHead: EventId.ROOT,
255
- localHead: e_0_0.id,
256
- }
257
- const result = run({
274
+ localHead: e1_0.id,
275
+ })
276
+ const result = merge({
258
277
  syncState,
259
- payload: { _tag: 'upstream-advance', newEvents: [e_0_0] },
260
- ignoreLocalEvents: true,
278
+ payload: { _tag: 'upstream-advance', newEvents: [e1_0] },
279
+ ignoreClientEvents: true,
261
280
  })
262
281
  expectAdvance(result)
263
- expectEventArraysEqual(result.newSyncState.pending, [e_1_0])
264
- expectEventArraysEqual(result.newSyncState.rollbackTail, [e_r_1, e_0_0])
265
- expect(result.newSyncState.upstreamHead).toBe(e_0_0.id)
266
- expect(result.newSyncState.localHead).toMatchObject(e_1_0.id)
267
- expect(result.newEvents).toEqual([])
282
+ expectEventArraysEqual(result.newSyncState.pending, [e2_0])
283
+ expect(result.newSyncState.upstreamHead).toMatchObject(e1_0.id)
284
+ expect(result.newSyncState.localHead).toMatchObject(e2_0.id)
285
+ expectEventArraysEqual(result.newEvents, [])
286
+ expectEventArraysEqual(result.confirmedEvents, [e0_1, e1_0])
268
287
  })
269
288
 
270
- it('should ignore local events (incoming goes beyond pending)', () => {
271
- const syncState = {
272
- pending: [e_r_1, e_0_0, e_0_1],
273
- rollbackTail: [],
289
+ it('should ignore client events (incoming goes beyond pending)', () => {
290
+ const syncState = new SyncState.SyncState({
291
+ pending: [e0_1, e1_0, e1_1],
274
292
  upstreamHead: EventId.ROOT,
275
- localHead: e_0_1.id,
276
- }
277
- const result = run({
293
+ localHead: e1_1.id,
294
+ })
295
+ const result = merge({
278
296
  syncState,
279
- payload: { _tag: 'upstream-advance', newEvents: [e_0_0, e_1_0] },
280
- ignoreLocalEvents: true,
297
+ payload: { _tag: 'upstream-advance', newEvents: [e1_0, e2_0] },
298
+ ignoreClientEvents: true,
281
299
  })
282
300
 
283
301
  expectAdvance(result)
284
302
  expectEventArraysEqual(result.newSyncState.pending, [])
285
- expectEventArraysEqual(result.newSyncState.rollbackTail, [e_r_1, e_0_0, e_0_1, e_1_0])
286
- expect(result.newSyncState.upstreamHead).toBe(e_1_0.id)
287
- expect(result.newSyncState.localHead).toMatchObject(e_1_0.id)
288
- expect(result.newEvents).toEqual([e_1_0])
303
+ expect(result.newSyncState.upstreamHead).toMatchObject(e2_0.id)
304
+ expect(result.newSyncState.localHead).toMatchObject(e2_0.id)
305
+ expect(result.newEvents).toStrictEqual([e2_0])
306
+ expectEventArraysEqual(result.confirmedEvents, [e0_1, e1_0, e1_1])
289
307
  })
290
- })
291
308
 
292
- describe('upstream-advance: rebase', () => {
293
- it('should rebase single local event to end', () => {
294
- const syncState = { pending: [e_0_0], rollbackTail: [], upstreamHead: EventId.ROOT, localHead: e_0_0.id }
295
- const result = run({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_1] } })
296
-
297
- const e_0_0_e_0_2 = e_0_0.rebase_(e_0_1.id)
298
-
299
- expectRebase(result)
300
- expectEventArraysEqual(result.newSyncState.pending, [e_0_0_e_0_2])
301
- expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_1])
302
- expect(result.newSyncState.upstreamHead).toBe(e_0_1.id)
303
- expect(result.newSyncState.localHead).toMatchObject(e_0_0_e_0_2.id)
304
- expectEventArraysEqual(result.eventsToRollback, [e_0_0])
305
- expectEventArraysEqual(result.newEvents, [e_0_1, e_0_0_e_0_2])
309
+ it('should fail if incoming event is ≤ local head', () => {
310
+ const syncState = new SyncState.SyncState({
311
+ pending: [],
312
+ upstreamHead: e2_0.id,
313
+ localHead: e2_0.id,
314
+ })
315
+ const result = merge({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e1_0] } })
316
+ expect(result).toMatchObject({ _tag: 'unexpected-error' })
306
317
  })
318
+ })
307
319
 
308
- it('should rebase different event with same id (no rollback tail)', () => {
309
- const e_0_0_b = new TestEvent({ global: 0, local: 0 }, EventId.ROOT, '0_0_b', true)
310
- const syncState = { pending: [e_0_0_b], rollbackTail: [], upstreamHead: EventId.ROOT, localHead: e_0_0_b.id }
311
- const result = run({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_0_0] } })
320
+ describe('upstream-advance: rebase', () => {
321
+ it('should rebase single client event to end', () => {
322
+ const syncState = new SyncState.SyncState({
323
+ pending: [e1_0],
324
+ upstreamHead: EventId.ROOT,
325
+ localHead: e1_0.id,
326
+ })
327
+ const result = merge({ syncState, payload: SyncState.PayloadUpstreamAdvance.make({ newEvents: [e1_1] }) })
312
328
 
313
- const e_0_0_e_1_0 = e_0_0_b.rebase_(e_0_0.id)
329
+ const e1_0_e1_2 = e1_0.rebase_(e1_1.id)
314
330
 
315
331
  expectRebase(result)
316
- expectEventArraysEqual(result.newSyncState.pending, [e_0_0_e_1_0])
317
- expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_0])
318
- expectEventArraysEqual(result.newEvents, [e_0_0, e_0_0_e_1_0])
319
- expectEventArraysEqual(result.eventsToRollback, [e_0_0_b])
320
- expect(result.newSyncState.upstreamHead).toBe(e_0_0.id)
321
- expect(result.newSyncState.localHead).toMatchObject(e_0_0_e_1_0.id)
332
+ expectEventArraysEqual(result.newSyncState.pending, [e1_0_e1_2])
333
+ expect(result.newSyncState.upstreamHead).toMatchObject(e1_1.id)
334
+ expect(result.newSyncState.localHead).toMatchObject(e1_0_e1_2.id)
335
+ expectEventArraysEqual(result.rollbackEvents, [e1_0])
336
+ expectEventArraysEqual(result.newEvents, [e1_1, e1_0_e1_2])
322
337
  })
323
338
 
324
339
  it('should rebase different event with same id', () => {
325
- const e_1_0_b = new TestEvent({ global: 1, local: 0 }, e_0_0.id, '1_0_b', false)
326
- const syncState = {
327
- pending: [e_1_0_b],
328
- rollbackTail: [e_0_0, e_0_1],
340
+ const e2_0_b = new TestEvent({ global: 1, client: 0 }, e1_0.id, '1_0_b', false)
341
+ const syncState = new SyncState.SyncState({
342
+ pending: [e2_0_b],
329
343
  upstreamHead: EventId.ROOT,
330
- localHead: e_1_0_b.id,
331
- }
332
- const result = run({ syncState, payload: { _tag: 'upstream-advance', newEvents: [e_1_0] } })
333
- const e_1_0_e_2_0 = e_1_0_b.rebase_(e_1_0.id)
344
+ localHead: e2_0_b.id,
345
+ })
346
+ const result = merge({ syncState, payload: SyncState.PayloadUpstreamAdvance.make({ newEvents: [e2_0] }) })
347
+ const e2_0_e3_0 = e2_0_b.rebase_(e2_0.id)
334
348
 
335
349
  expectRebase(result)
336
- expectEventArraysEqual(result.newSyncState.pending, [e_1_0_e_2_0])
337
- expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_0, e_0_1, e_1_0])
338
- expectEventArraysEqual(result.newEvents, [e_1_0, e_1_0_e_2_0])
339
- expectEventArraysEqual(result.eventsToRollback, [e_0_0, e_0_1, e_1_0_b])
340
- expect(result.newSyncState.upstreamHead).toBe(e_1_0.id)
341
- expect(result.newSyncState.localHead).toMatchObject(e_1_0_e_2_0.id)
350
+ expectEventArraysEqual(result.newSyncState.pending, [e2_0_e3_0])
351
+ expectEventArraysEqual(result.newEvents, [e2_0, e2_0_e3_0])
352
+ expectEventArraysEqual(result.rollbackEvents, [e2_0_b])
353
+ expect(result.newSyncState.upstreamHead).toMatchObject(e2_0.id)
354
+ expect(result.newSyncState.localHead).toMatchObject(e2_0_e3_0.id)
342
355
  })
343
356
 
344
- it('should rebase single local event to end (more incoming events)', () => {
345
- const syncState = { pending: [e_0_0], rollbackTail: [], upstreamHead: EventId.ROOT, localHead: e_0_0.id }
346
- const result = run({
357
+ it('should rebase single client event to end (more incoming events)', () => {
358
+ const syncState = new SyncState.SyncState({
359
+ pending: [e1_0],
360
+ upstreamHead: EventId.ROOT,
361
+ localHead: e1_0.id,
362
+ })
363
+ const result = merge({
347
364
  syncState,
348
- payload: { _tag: 'upstream-advance', newEvents: [e_0_1, e_0_2, e_0_3, e_1_0] },
365
+ payload: SyncState.PayloadUpstreamAdvance.make({ newEvents: [e1_1, e1_2, e1_3, e2_0] }),
349
366
  })
350
367
 
351
- const e_0_0_e_2_0 = e_0_0.rebase_(e_1_0.id)
368
+ const e1_0_e3_0 = e1_0.rebase_(e2_0.id)
352
369
 
353
370
  expectRebase(result)
354
- expectEventArraysEqual(result.newSyncState.pending, [e_0_0_e_2_0])
355
- expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_1, e_0_2, e_0_3, e_1_0])
356
- expect(result.newSyncState.upstreamHead).toBe(e_1_0.id)
357
- expect(result.newSyncState.localHead).toMatchObject(e_0_0_e_2_0.id)
371
+ expectEventArraysEqual(result.newSyncState.pending, [e1_0_e3_0])
372
+ expect(result.newSyncState.upstreamHead).toMatchObject(e2_0.id)
373
+ expect(result.newSyncState.localHead).toMatchObject(e1_0_e3_0.id)
358
374
  })
359
375
 
360
376
  it('should only rebase divergent events when first event matches', () => {
361
- const syncState = {
362
- pending: [e_0_0, e_0_1],
363
- rollbackTail: [],
377
+ const syncState = new SyncState.SyncState({
378
+ pending: [e1_0, e1_1],
364
379
  upstreamHead: EventId.ROOT,
365
- localHead: e_0_0.id,
366
- }
367
- const result = run({
380
+ localHead: e1_0.id,
381
+ })
382
+ const result = merge({
368
383
  syncState,
369
- payload: { _tag: 'upstream-advance', newEvents: [e_0_0, e_0_2, e_0_3, e_1_0] },
384
+ payload: SyncState.PayloadUpstreamAdvance.make({ newEvents: [e1_0, e1_2, e1_3, e2_0] }),
370
385
  })
371
386
 
372
- const e_0_1_e_1_1 = e_0_1.rebase_(e_1_0.id)
387
+ const e1_1_e2_1 = e1_1.rebase_(e2_0.id)
373
388
 
374
389
  expectRebase(result)
375
- expectEventArraysEqual(result.newSyncState.pending, [e_0_1_e_1_1])
376
- expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_0, e_0_2, e_0_3, e_1_0])
377
- expectEventArraysEqual(result.eventsToRollback, [e_0_1])
378
- expectEventArraysEqual(result.newEvents, [e_0_2, e_0_3, e_1_0, e_0_1_e_1_1])
379
- expect(result.newSyncState.upstreamHead).toBe(e_1_0.id)
380
- expect(result.newSyncState.localHead).toMatchObject(e_0_1_e_1_1.id)
390
+ expectEventArraysEqual(result.newSyncState.pending, [e1_1_e2_1])
391
+ expectEventArraysEqual(result.rollbackEvents, [e1_1])
392
+ expectEventArraysEqual(result.newEvents, [e1_2, e1_3, e2_0, e1_1_e2_1])
393
+ expect(result.newSyncState.upstreamHead).toMatchObject(e2_0.id)
394
+ expect(result.newSyncState.localHead).toMatchObject(e1_1_e2_1.id)
381
395
  })
382
396
 
383
- it('should rebase all local events when incoming chain starts differently', () => {
384
- const syncState = {
385
- pending: [e_0_0, e_0_1],
386
- rollbackTail: [],
397
+ it('should rebase all client events when incoming chain starts differently', () => {
398
+ const syncState = new SyncState.SyncState({
399
+ pending: [e1_0, e1_1],
387
400
  upstreamHead: EventId.ROOT,
388
- localHead: e_0_1.id,
389
- }
390
- const result = run({
401
+ localHead: e1_1.id,
402
+ })
403
+ const result = merge({
391
404
  syncState,
392
- payload: { _tag: 'upstream-advance', newEvents: [e_0_1, e_0_2, e_0_3, e_1_0] },
405
+ payload: SyncState.PayloadUpstreamAdvance.make({ newEvents: [e1_1, e1_2, e1_3, e2_0] }),
393
406
  })
394
407
 
395
- const e_0_0_e_1_1 = e_0_0.rebase_(e_1_0.id)
396
- const e_0_1_e_1_2 = e_0_1.rebase_(e_0_0_e_1_1.id)
408
+ const e1_0_e2_1 = e1_0.rebase_(e2_0.id)
409
+ const e1_1_e2_2 = e1_1.rebase_(e1_0_e2_1.id)
397
410
 
398
411
  expectRebase(result)
399
- expectEventArraysEqual(result.newSyncState.pending, [e_0_0_e_1_1, e_0_1_e_1_2])
400
- expectEventArraysEqual(result.newSyncState.rollbackTail, [e_0_1, e_0_2, e_0_3, e_1_0])
401
- expectEventArraysEqual(result.newEvents, [e_0_1, e_0_2, e_0_3, e_1_0, e_0_0_e_1_1, e_0_1_e_1_2])
402
- expectEventArraysEqual(result.eventsToRollback, [e_0_0, e_0_1])
403
- expect(result.newSyncState.upstreamHead).toBe(e_1_0.id)
404
- expect(result.newSyncState.localHead).toMatchObject(e_0_1_e_1_2.id)
412
+ expectEventArraysEqual(result.newSyncState.pending, [e1_0_e2_1, e1_1_e2_2])
413
+ expectEventArraysEqual(result.newEvents, [e1_1, e1_2, e1_3, e2_0, e1_0_e2_1, e1_1_e2_2])
414
+ expectEventArraysEqual(result.rollbackEvents, [e1_0, e1_1])
415
+ expect(result.newSyncState.upstreamHead).toMatchObject(e2_0.id)
416
+ expect(result.newSyncState.localHead).toMatchObject(e1_1_e2_2.id)
405
417
  })
406
418
 
407
419
  describe('local-push', () => {
408
420
  describe('advance', () => {
409
421
  it('should advance with new events', () => {
410
- const syncState = { pending: [e_0_0], rollbackTail: [], upstreamHead: EventId.ROOT, localHead: e_0_0.id }
411
- const result = run({ syncState, payload: { _tag: 'local-push', newEvents: [e_0_1, e_0_2, e_0_3] } })
422
+ const syncState = new SyncState.SyncState({
423
+ pending: [e1_0],
424
+ upstreamHead: EventId.ROOT,
425
+ localHead: e1_0.id,
426
+ })
427
+ const result = merge({
428
+ syncState,
429
+ payload: SyncState.PayloadLocalPush.make({ newEvents: [e1_1, e1_2, e1_3] }),
430
+ })
412
431
 
413
432
  expectAdvance(result)
414
- expectEventArraysEqual(result.newSyncState.pending, [e_0_0, e_0_1, e_0_2, e_0_3])
415
- expectEventArraysEqual(result.newSyncState.rollbackTail, [])
416
- expect(result.newSyncState.upstreamHead).toBe(EventId.ROOT)
417
- expect(result.newSyncState.localHead).toMatchObject(e_0_3.id)
418
- expectEventArraysEqual(result.newEvents, [e_0_1, e_0_2, e_0_3])
433
+ expectEventArraysEqual(result.newSyncState.pending, [e1_0, e1_1, e1_2, e1_3])
434
+ expect(result.newSyncState.upstreamHead).toMatchObject(EventId.ROOT)
435
+ expect(result.newSyncState.localHead).toMatchObject(e1_3.id)
436
+ expectEventArraysEqual(result.newEvents, [e1_1, e1_2, e1_3])
437
+ expectEventArraysEqual(result.confirmedEvents, [])
419
438
  })
420
439
  })
421
440
 
422
441
  describe('reject', () => {
423
442
  it('should reject when new events are greater than pending events', () => {
424
- const syncState = {
425
- pending: [e_0_0, e_0_1],
426
- rollbackTail: [],
443
+ const syncState = new SyncState.SyncState({
444
+ pending: [e1_0, e1_1],
427
445
  upstreamHead: EventId.ROOT,
428
- localHead: e_0_1.id,
429
- }
430
- const result = run({ syncState, payload: { _tag: 'local-push', newEvents: [e_0_1, e_0_2] } })
446
+ localHead: e1_1.id,
447
+ })
448
+ const result = merge({
449
+ syncState,
450
+ payload: SyncState.PayloadLocalPush.make({ newEvents: [e1_1, e1_2] }),
451
+ })
431
452
 
432
453
  expectReject(result)
433
- expect(result.expectedMinimumId).toMatchObject(e_0_2.id)
454
+ expect(result.expectedMinimumId).toMatchObject(e1_2.id)
434
455
  })
435
456
  })
436
457
  })
@@ -439,26 +460,32 @@ describe('syncstate', () => {
439
460
  })
440
461
 
441
462
  const expectEventArraysEqual = (
442
- actual: ReadonlyArray<MutationEvent.EncodedWithMeta>,
443
- expected: ReadonlyArray<MutationEvent.EncodedWithMeta>,
463
+ actual: ReadonlyArray<LiveStoreEvent.EncodedWithMeta>,
464
+ expected: ReadonlyArray<LiveStoreEvent.EncodedWithMeta>,
444
465
  ) => {
445
466
  expect(actual.length).toBe(expected.length)
446
467
  actual.forEach((event, i) => {
447
- expect(event.id).toEqual(expected[i]!.id)
448
- expect(event.parentId).toEqual(expected[i]!.parentId)
449
- expect(event.mutation).toEqual(expected[i]!.mutation)
450
- expect(event.args).toEqual(expected[i]!.args)
468
+ expect(event.id).toStrictEqual(expected[i]!.id)
469
+ expect(event.parentId).toStrictEqual(expected[i]!.parentId)
470
+ expect(event.name).toStrictEqual(expected[i]!.name)
471
+ expect(event.args).toStrictEqual(expected[i]!.args)
451
472
  })
452
473
  }
453
474
 
454
- function expectAdvance(result: SyncState.UpdateResult): asserts result is SyncState.UpdateResultAdvance {
475
+ function expectAdvance(
476
+ result: typeof SyncState.MergeResult.Type,
477
+ ): asserts result is typeof SyncState.MergeResultAdvance.Type {
455
478
  expect(result._tag).toBe('advance')
456
479
  }
457
480
 
458
- function expectRebase(result: SyncState.UpdateResult): asserts result is SyncState.UpdateResultRebase {
459
- expect(result._tag).toBe('rebase')
481
+ function expectRebase(
482
+ result: typeof SyncState.MergeResult.Type,
483
+ ): asserts result is typeof SyncState.MergeResultRebase.Type {
484
+ expect(result._tag, `Expected rebase, got ${result}`).toBe('rebase')
460
485
  }
461
486
 
462
- function expectReject(result: SyncState.UpdateResult): asserts result is SyncState.UpdateResultReject {
487
+ function expectReject(
488
+ result: typeof SyncState.MergeResult.Type,
489
+ ): asserts result is typeof SyncState.MergeResultReject.Type {
463
490
  expect(result._tag).toBe('reject')
464
491
  }