tinybase 5.0.0-beta.0 → 5.0.0-beta.10

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 (493) hide show
  1. package/bin/cli.js +1 -1
  2. package/lib/checkpoints.js +1 -1
  3. package/lib/checkpoints.js.gz +0 -0
  4. package/lib/cjs/checkpoints.cjs +1 -1
  5. package/lib/cjs/checkpoints.cjs.gz +0 -0
  6. package/lib/cjs/indexes.cjs +1 -1
  7. package/lib/cjs/indexes.cjs.gz +0 -0
  8. package/lib/cjs/mergeable-store.cjs +1 -0
  9. package/lib/cjs/mergeable-store.cjs.gz +0 -0
  10. package/lib/cjs/metrics.cjs +1 -1
  11. package/lib/cjs/metrics.cjs.gz +0 -0
  12. package/lib/cjs/persisters/persister-automerge.cjs +1 -1
  13. package/lib/cjs/persisters/persister-automerge.cjs.gz +0 -0
  14. package/lib/cjs/persisters/persister-browser.cjs +1 -1
  15. package/lib/cjs/persisters/persister-browser.cjs.gz +0 -0
  16. package/lib/cjs/persisters/persister-cr-sqlite-wasm.cjs +1 -1
  17. package/lib/cjs/persisters/persister-cr-sqlite-wasm.cjs.gz +0 -0
  18. package/lib/cjs/persisters/persister-electric-sql.cjs +1 -1
  19. package/lib/cjs/persisters/persister-electric-sql.cjs.gz +0 -0
  20. package/lib/cjs/persisters/persister-expo-sqlite-next.cjs +1 -1
  21. package/lib/cjs/persisters/persister-expo-sqlite-next.cjs.gz +0 -0
  22. package/lib/cjs/persisters/persister-expo-sqlite.cjs +1 -1
  23. package/lib/cjs/persisters/persister-expo-sqlite.cjs.gz +0 -0
  24. package/lib/cjs/persisters/persister-file.cjs +1 -1
  25. package/lib/cjs/persisters/persister-file.cjs.gz +0 -0
  26. package/lib/cjs/persisters/persister-indexed-db.cjs +1 -1
  27. package/lib/cjs/persisters/persister-indexed-db.cjs.gz +0 -0
  28. package/lib/cjs/persisters/persister-libsql.cjs +1 -0
  29. package/lib/cjs/persisters/persister-libsql.cjs.gz +0 -0
  30. package/lib/cjs/persisters/persister-partykit-client.cjs +1 -1
  31. package/lib/cjs/persisters/persister-partykit-client.cjs.gz +0 -0
  32. package/lib/cjs/persisters/persister-partykit-server.cjs +1 -1
  33. package/lib/cjs/persisters/persister-partykit-server.cjs.gz +0 -0
  34. package/lib/cjs/persisters/persister-powersync.cjs +1 -0
  35. package/lib/cjs/persisters/persister-powersync.cjs.gz +0 -0
  36. package/lib/cjs/persisters/persister-remote.cjs +1 -1
  37. package/lib/cjs/persisters/persister-remote.cjs.gz +0 -0
  38. package/lib/cjs/persisters/persister-sqlite-wasm.cjs +1 -1
  39. package/lib/cjs/persisters/persister-sqlite-wasm.cjs.gz +0 -0
  40. package/lib/cjs/persisters/persister-sqlite3.cjs +1 -1
  41. package/lib/cjs/persisters/persister-sqlite3.cjs.gz +0 -0
  42. package/lib/cjs/persisters/persister-yjs.cjs +1 -1
  43. package/lib/cjs/persisters/persister-yjs.cjs.gz +0 -0
  44. package/lib/cjs/persisters.cjs +1 -1
  45. package/lib/cjs/persisters.cjs.gz +0 -0
  46. package/lib/cjs/queries.cjs +1 -1
  47. package/lib/cjs/queries.cjs.gz +0 -0
  48. package/lib/cjs/relationships.cjs +1 -1
  49. package/lib/cjs/relationships.cjs.gz +0 -0
  50. package/lib/cjs/store.cjs +1 -1
  51. package/lib/cjs/store.cjs.gz +0 -0
  52. package/lib/cjs/synchronizers/synchronizer-local.cjs +1 -0
  53. package/lib/cjs/synchronizers/synchronizer-local.cjs.gz +0 -0
  54. package/lib/cjs/synchronizers/synchronizer-ws-client.cjs +1 -0
  55. package/lib/cjs/synchronizers/synchronizer-ws-client.cjs.gz +0 -0
  56. package/lib/cjs/synchronizers/synchronizer-ws-server.cjs +1 -0
  57. package/lib/cjs/synchronizers/synchronizer-ws-server.cjs.gz +0 -0
  58. package/lib/cjs/synchronizers.cjs +1 -0
  59. package/lib/cjs/synchronizers.cjs.gz +0 -0
  60. package/lib/cjs/tinybase.cjs +1 -1
  61. package/lib/cjs/tinybase.cjs.gz +0 -0
  62. package/lib/cjs/tools.cjs +1 -1
  63. package/lib/cjs/tools.cjs.gz +0 -0
  64. package/lib/cjs/ui-react-dom-debug.cjs +1 -1
  65. package/lib/cjs/ui-react-dom-debug.cjs.gz +0 -0
  66. package/lib/cjs/ui-react-dom.cjs +1 -1
  67. package/lib/cjs/ui-react-dom.cjs.gz +0 -0
  68. package/lib/cjs/ui-react.cjs +1 -1
  69. package/lib/cjs/ui-react.cjs.gz +0 -0
  70. package/lib/cjs-es6/checkpoints.cjs +1 -1
  71. package/lib/cjs-es6/checkpoints.cjs.gz +0 -0
  72. package/lib/cjs-es6/indexes.cjs +1 -1
  73. package/lib/cjs-es6/indexes.cjs.gz +0 -0
  74. package/lib/cjs-es6/mergeable-store.cjs +1 -0
  75. package/lib/cjs-es6/mergeable-store.cjs.gz +0 -0
  76. package/lib/cjs-es6/metrics.cjs +1 -1
  77. package/lib/cjs-es6/metrics.cjs.gz +0 -0
  78. package/lib/cjs-es6/persisters/persister-automerge.cjs +1 -1
  79. package/lib/cjs-es6/persisters/persister-automerge.cjs.gz +0 -0
  80. package/lib/cjs-es6/persisters/persister-browser.cjs +1 -1
  81. package/lib/cjs-es6/persisters/persister-browser.cjs.gz +0 -0
  82. package/lib/cjs-es6/persisters/persister-cr-sqlite-wasm.cjs +1 -1
  83. package/lib/cjs-es6/persisters/persister-cr-sqlite-wasm.cjs.gz +0 -0
  84. package/lib/cjs-es6/persisters/persister-electric-sql.cjs +1 -1
  85. package/lib/cjs-es6/persisters/persister-electric-sql.cjs.gz +0 -0
  86. package/lib/cjs-es6/persisters/persister-expo-sqlite-next.cjs +1 -1
  87. package/lib/cjs-es6/persisters/persister-expo-sqlite-next.cjs.gz +0 -0
  88. package/lib/cjs-es6/persisters/persister-expo-sqlite.cjs +1 -1
  89. package/lib/cjs-es6/persisters/persister-expo-sqlite.cjs.gz +0 -0
  90. package/lib/cjs-es6/persisters/persister-file.cjs +1 -1
  91. package/lib/cjs-es6/persisters/persister-file.cjs.gz +0 -0
  92. package/lib/cjs-es6/persisters/persister-indexed-db.cjs +1 -1
  93. package/lib/cjs-es6/persisters/persister-indexed-db.cjs.gz +0 -0
  94. package/lib/cjs-es6/persisters/persister-libsql.cjs +1 -0
  95. package/lib/cjs-es6/persisters/persister-libsql.cjs.gz +0 -0
  96. package/lib/cjs-es6/persisters/persister-partykit-client.cjs +1 -1
  97. package/lib/cjs-es6/persisters/persister-partykit-client.cjs.gz +0 -0
  98. package/lib/cjs-es6/persisters/persister-partykit-server.cjs +1 -1
  99. package/lib/cjs-es6/persisters/persister-partykit-server.cjs.gz +0 -0
  100. package/lib/cjs-es6/persisters/persister-powersync.cjs +1 -0
  101. package/lib/cjs-es6/persisters/persister-powersync.cjs.gz +0 -0
  102. package/lib/cjs-es6/persisters/persister-remote.cjs +1 -1
  103. package/lib/cjs-es6/persisters/persister-remote.cjs.gz +0 -0
  104. package/lib/cjs-es6/persisters/persister-sqlite-wasm.cjs +1 -1
  105. package/lib/cjs-es6/persisters/persister-sqlite-wasm.cjs.gz +0 -0
  106. package/lib/cjs-es6/persisters/persister-sqlite3.cjs +1 -1
  107. package/lib/cjs-es6/persisters/persister-sqlite3.cjs.gz +0 -0
  108. package/lib/cjs-es6/persisters/persister-yjs.cjs +1 -1
  109. package/lib/cjs-es6/persisters/persister-yjs.cjs.gz +0 -0
  110. package/lib/cjs-es6/persisters.cjs +1 -1
  111. package/lib/cjs-es6/persisters.cjs.gz +0 -0
  112. package/lib/cjs-es6/queries.cjs +1 -1
  113. package/lib/cjs-es6/queries.cjs.gz +0 -0
  114. package/lib/cjs-es6/relationships.cjs +1 -1
  115. package/lib/cjs-es6/relationships.cjs.gz +0 -0
  116. package/lib/cjs-es6/store.cjs +1 -1
  117. package/lib/cjs-es6/store.cjs.gz +0 -0
  118. package/lib/cjs-es6/synchronizers/synchronizer-local.cjs +1 -0
  119. package/lib/cjs-es6/synchronizers/synchronizer-local.cjs.gz +0 -0
  120. package/lib/cjs-es6/synchronizers/synchronizer-ws-client.cjs +1 -0
  121. package/lib/cjs-es6/synchronizers/synchronizer-ws-client.cjs.gz +0 -0
  122. package/lib/cjs-es6/synchronizers/synchronizer-ws-server.cjs +1 -0
  123. package/lib/cjs-es6/synchronizers/synchronizer-ws-server.cjs.gz +0 -0
  124. package/lib/cjs-es6/synchronizers.cjs +1 -0
  125. package/lib/cjs-es6/synchronizers.cjs.gz +0 -0
  126. package/lib/cjs-es6/tinybase.cjs +1 -1
  127. package/lib/cjs-es6/tinybase.cjs.gz +0 -0
  128. package/lib/cjs-es6/tools.cjs +1 -1
  129. package/lib/cjs-es6/tools.cjs.gz +0 -0
  130. package/lib/cjs-es6/ui-react-dom-debug.cjs +1 -1
  131. package/lib/cjs-es6/ui-react-dom-debug.cjs.gz +0 -0
  132. package/lib/cjs-es6/ui-react-dom.cjs +1 -1
  133. package/lib/cjs-es6/ui-react-dom.cjs.gz +0 -0
  134. package/lib/cjs-es6/ui-react.cjs +1 -1
  135. package/lib/cjs-es6/ui-react.cjs.gz +0 -0
  136. package/lib/debug/checkpoints.js +254 -235
  137. package/lib/debug/indexes.js +10 -6
  138. package/lib/debug/mergeable-store.js +2230 -0
  139. package/lib/debug/metrics.js +10 -6
  140. package/lib/debug/persisters/persister-automerge.js +113 -87
  141. package/lib/debug/persisters/persister-browser.js +95 -57
  142. package/lib/debug/persisters/persister-cr-sqlite-wasm.js +175 -109
  143. package/lib/debug/persisters/persister-electric-sql.js +176 -109
  144. package/lib/debug/persisters/persister-expo-sqlite-next.js +176 -110
  145. package/lib/debug/persisters/persister-expo-sqlite.js +175 -109
  146. package/lib/debug/persisters/persister-file.js +94 -57
  147. package/lib/debug/persisters/persister-indexed-db.js +94 -57
  148. package/lib/debug/persisters/persister-libsql.js +913 -0
  149. package/lib/debug/persisters/persister-partykit-client.js +90 -59
  150. package/lib/debug/persisters/persister-partykit-server.js +19 -26
  151. package/lib/debug/persisters/persister-powersync.js +928 -0
  152. package/lib/debug/persisters/persister-remote.js +86 -53
  153. package/lib/debug/persisters/persister-sqlite-wasm.js +175 -109
  154. package/lib/debug/persisters/persister-sqlite3.js +175 -109
  155. package/lib/debug/persisters/persister-yjs.js +111 -84
  156. package/lib/debug/persisters.js +82 -50
  157. package/lib/debug/queries.js +18 -12
  158. package/lib/debug/relationships.js +10 -6
  159. package/lib/debug/store.js +150 -127
  160. package/lib/debug/synchronizers/synchronizer-local.js +559 -0
  161. package/lib/debug/synchronizers/synchronizer-ws-client.js +586 -0
  162. package/lib/debug/synchronizers/synchronizer-ws-server.js +96 -0
  163. package/lib/debug/synchronizers.js +519 -0
  164. package/lib/debug/tinybase.js +1281 -409
  165. package/lib/debug/tools.js +41 -64
  166. package/lib/debug/ui-react-dom.js +277 -213
  167. package/lib/debug/ui-react.js +213 -198
  168. package/lib/es6/checkpoints.js +1 -1
  169. package/lib/es6/checkpoints.js.gz +0 -0
  170. package/lib/es6/indexes.js +1 -1
  171. package/lib/es6/indexes.js.gz +0 -0
  172. package/lib/es6/mergeable-store.js +1 -0
  173. package/lib/es6/mergeable-store.js.gz +0 -0
  174. package/lib/es6/metrics.js +1 -1
  175. package/lib/es6/metrics.js.gz +0 -0
  176. package/lib/es6/persisters/persister-automerge.js +1 -1
  177. package/lib/es6/persisters/persister-automerge.js.gz +0 -0
  178. package/lib/es6/persisters/persister-browser.js +1 -1
  179. package/lib/es6/persisters/persister-browser.js.gz +0 -0
  180. package/lib/es6/persisters/persister-cr-sqlite-wasm.js +1 -1
  181. package/lib/es6/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
  182. package/lib/es6/persisters/persister-electric-sql.js +1 -1
  183. package/lib/es6/persisters/persister-electric-sql.js.gz +0 -0
  184. package/lib/es6/persisters/persister-expo-sqlite-next.js +1 -1
  185. package/lib/es6/persisters/persister-expo-sqlite-next.js.gz +0 -0
  186. package/lib/es6/persisters/persister-expo-sqlite.js +1 -1
  187. package/lib/es6/persisters/persister-expo-sqlite.js.gz +0 -0
  188. package/lib/es6/persisters/persister-file.js +1 -1
  189. package/lib/es6/persisters/persister-file.js.gz +0 -0
  190. package/lib/es6/persisters/persister-indexed-db.js +1 -1
  191. package/lib/es6/persisters/persister-indexed-db.js.gz +0 -0
  192. package/lib/es6/persisters/persister-libsql.js +1 -0
  193. package/lib/es6/persisters/persister-libsql.js.gz +0 -0
  194. package/lib/es6/persisters/persister-partykit-client.js +1 -1
  195. package/lib/es6/persisters/persister-partykit-client.js.gz +0 -0
  196. package/lib/es6/persisters/persister-partykit-server.js +1 -1
  197. package/lib/es6/persisters/persister-partykit-server.js.gz +0 -0
  198. package/lib/es6/persisters/persister-powersync.js +1 -0
  199. package/lib/es6/persisters/persister-powersync.js.gz +0 -0
  200. package/lib/es6/persisters/persister-remote.js +1 -1
  201. package/lib/es6/persisters/persister-remote.js.gz +0 -0
  202. package/lib/es6/persisters/persister-sqlite-wasm.js +1 -1
  203. package/lib/es6/persisters/persister-sqlite-wasm.js.gz +0 -0
  204. package/lib/es6/persisters/persister-sqlite3.js +1 -1
  205. package/lib/es6/persisters/persister-sqlite3.js.gz +0 -0
  206. package/lib/es6/persisters/persister-yjs.js +1 -1
  207. package/lib/es6/persisters/persister-yjs.js.gz +0 -0
  208. package/lib/es6/persisters.js +1 -1
  209. package/lib/es6/persisters.js.gz +0 -0
  210. package/lib/es6/queries.js +1 -1
  211. package/lib/es6/queries.js.gz +0 -0
  212. package/lib/es6/relationships.js +1 -1
  213. package/lib/es6/relationships.js.gz +0 -0
  214. package/lib/es6/store.js +1 -1
  215. package/lib/es6/store.js.gz +0 -0
  216. package/lib/es6/synchronizers/synchronizer-local.js +1 -0
  217. package/lib/es6/synchronizers/synchronizer-local.js.gz +0 -0
  218. package/lib/es6/synchronizers/synchronizer-ws-client.js +1 -0
  219. package/lib/es6/synchronizers/synchronizer-ws-client.js.gz +0 -0
  220. package/lib/es6/synchronizers/synchronizer-ws-server.js +1 -0
  221. package/lib/es6/synchronizers/synchronizer-ws-server.js.gz +0 -0
  222. package/lib/es6/synchronizers.js +1 -0
  223. package/lib/es6/synchronizers.js.gz +0 -0
  224. package/lib/es6/tinybase.js +1 -1
  225. package/lib/es6/tinybase.js.gz +0 -0
  226. package/lib/es6/tools.js +1 -1
  227. package/lib/es6/tools.js.gz +0 -0
  228. package/lib/es6/ui-react-dom-debug.js +1 -1
  229. package/lib/es6/ui-react-dom-debug.js.gz +0 -0
  230. package/lib/es6/ui-react-dom.js +1 -1
  231. package/lib/es6/ui-react-dom.js.gz +0 -0
  232. package/lib/es6/ui-react.js +1 -1
  233. package/lib/es6/ui-react.js.gz +0 -0
  234. package/lib/indexes.js +1 -1
  235. package/lib/indexes.js.gz +0 -0
  236. package/lib/mergeable-store.js +1 -0
  237. package/lib/mergeable-store.js.gz +0 -0
  238. package/lib/metrics.js +1 -1
  239. package/lib/metrics.js.gz +0 -0
  240. package/lib/persisters/persister-automerge.js +1 -1
  241. package/lib/persisters/persister-automerge.js.gz +0 -0
  242. package/lib/persisters/persister-browser.js +1 -1
  243. package/lib/persisters/persister-browser.js.gz +0 -0
  244. package/lib/persisters/persister-cr-sqlite-wasm.js +1 -1
  245. package/lib/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
  246. package/lib/persisters/persister-electric-sql.js +1 -1
  247. package/lib/persisters/persister-electric-sql.js.gz +0 -0
  248. package/lib/persisters/persister-expo-sqlite-next.js +1 -1
  249. package/lib/persisters/persister-expo-sqlite-next.js.gz +0 -0
  250. package/lib/persisters/persister-expo-sqlite.js +1 -1
  251. package/lib/persisters/persister-expo-sqlite.js.gz +0 -0
  252. package/lib/persisters/persister-file.js +1 -1
  253. package/lib/persisters/persister-file.js.gz +0 -0
  254. package/lib/persisters/persister-indexed-db.js +1 -1
  255. package/lib/persisters/persister-indexed-db.js.gz +0 -0
  256. package/lib/persisters/persister-libsql.js +1 -0
  257. package/lib/persisters/persister-libsql.js.gz +0 -0
  258. package/lib/persisters/persister-partykit-client.js +1 -1
  259. package/lib/persisters/persister-partykit-client.js.gz +0 -0
  260. package/lib/persisters/persister-partykit-server.js +1 -1
  261. package/lib/persisters/persister-partykit-server.js.gz +0 -0
  262. package/lib/persisters/persister-powersync.js +1 -0
  263. package/lib/persisters/persister-powersync.js.gz +0 -0
  264. package/lib/persisters/persister-remote.js +1 -1
  265. package/lib/persisters/persister-remote.js.gz +0 -0
  266. package/lib/persisters/persister-sqlite-wasm.js +1 -1
  267. package/lib/persisters/persister-sqlite-wasm.js.gz +0 -0
  268. package/lib/persisters/persister-sqlite3.js +1 -1
  269. package/lib/persisters/persister-sqlite3.js.gz +0 -0
  270. package/lib/persisters/persister-yjs.js +1 -1
  271. package/lib/persisters/persister-yjs.js.gz +0 -0
  272. package/lib/persisters.js +1 -1
  273. package/lib/persisters.js.gz +0 -0
  274. package/lib/queries.js +1 -1
  275. package/lib/queries.js.gz +0 -0
  276. package/lib/relationships.js +1 -1
  277. package/lib/relationships.js.gz +0 -0
  278. package/lib/store.js +1 -1
  279. package/lib/store.js.gz +0 -0
  280. package/lib/synchronizers/synchronizer-local.js +1 -0
  281. package/lib/synchronizers/synchronizer-local.js.gz +0 -0
  282. package/lib/synchronizers/synchronizer-ws-client.js +1 -0
  283. package/lib/synchronizers/synchronizer-ws-client.js.gz +0 -0
  284. package/lib/synchronizers/synchronizer-ws-server.js +1 -0
  285. package/lib/synchronizers/synchronizer-ws-server.js.gz +0 -0
  286. package/lib/synchronizers.js +1 -0
  287. package/lib/synchronizers.js.gz +0 -0
  288. package/lib/tinybase.js +1 -1
  289. package/lib/tinybase.js.gz +0 -0
  290. package/lib/tools.js +1 -1
  291. package/lib/tools.js.gz +0 -0
  292. package/lib/types/checkpoints.d.ts +2 -2
  293. package/lib/types/indexes.d.ts +2 -2
  294. package/lib/types/mergeable-store.d.ts +214 -0
  295. package/lib/types/metrics.d.ts +2 -2
  296. package/lib/types/persisters/persister-automerge.d.ts +11 -7
  297. package/lib/types/persisters/persister-browser.d.ts +13 -4
  298. package/lib/types/persisters/persister-cr-sqlite-wasm.d.ts +4 -0
  299. package/lib/types/persisters/persister-electric-sql.d.ts +4 -0
  300. package/lib/types/persisters/persister-expo-sqlite-next.d.ts +7 -3
  301. package/lib/types/persisters/persister-expo-sqlite.d.ts +4 -0
  302. package/lib/types/persisters/persister-file.d.ts +7 -2
  303. package/lib/types/persisters/persister-indexed-db.d.ts +4 -0
  304. package/lib/types/persisters/persister-libsql.d.ts +142 -0
  305. package/lib/types/persisters/persister-partykit-client.d.ts +4 -0
  306. package/lib/types/persisters/persister-partykit-server.d.ts +12 -8
  307. package/lib/types/persisters/persister-powersync.d.ts +157 -0
  308. package/lib/types/persisters/persister-remote.d.ts +4 -0
  309. package/lib/types/persisters/persister-sqlite-wasm.d.ts +4 -0
  310. package/lib/types/persisters/persister-sqlite3.d.ts +4 -0
  311. package/lib/types/persisters/persister-yjs.d.ts +6 -2
  312. package/lib/types/persisters.d.ts +125 -48
  313. package/lib/types/queries.d.ts +2 -2
  314. package/lib/types/relationships.d.ts +2 -2
  315. package/lib/types/store.d.ts +275 -187
  316. package/lib/types/synchronizers/synchronizer-local.d.ts +27 -0
  317. package/lib/types/synchronizers/synchronizer-ws-client.d.ts +35 -0
  318. package/lib/types/synchronizers/synchronizer-ws-server.d.ts +36 -0
  319. package/lib/types/synchronizers.d.ts +132 -0
  320. package/lib/types/tinybase.d.ts +10 -8
  321. package/lib/types/tools.d.ts +4 -4
  322. package/lib/types/ui-react.d.ts +235 -95
  323. package/lib/types/with-schemas/checkpoints.d.ts +2 -2
  324. package/lib/types/with-schemas/indexes.d.ts +2 -2
  325. package/lib/types/with-schemas/internal/queries.d.ts +4 -3
  326. package/lib/types/with-schemas/internal/store.d.ts +8 -3
  327. package/lib/types/with-schemas/mergeable-store.d.ts +492 -0
  328. package/lib/types/with-schemas/metrics.d.ts +2 -2
  329. package/lib/types/with-schemas/persisters/persister-automerge.d.ts +12 -8
  330. package/lib/types/with-schemas/persisters/persister-browser.d.ts +17 -8
  331. package/lib/types/with-schemas/persisters/persister-cr-sqlite-wasm.d.ts +5 -1
  332. package/lib/types/with-schemas/persisters/persister-electric-sql.d.ts +5 -1
  333. package/lib/types/with-schemas/persisters/persister-expo-sqlite-next.d.ts +8 -4
  334. package/lib/types/with-schemas/persisters/persister-expo-sqlite.d.ts +5 -1
  335. package/lib/types/with-schemas/persisters/persister-file.d.ts +9 -4
  336. package/lib/types/with-schemas/persisters/persister-indexed-db.d.ts +5 -1
  337. package/lib/types/with-schemas/persisters/persister-libsql.d.ts +155 -0
  338. package/lib/types/with-schemas/persisters/persister-partykit-client.d.ts +5 -1
  339. package/lib/types/with-schemas/persisters/persister-partykit-server.d.ts +15 -11
  340. package/lib/types/with-schemas/persisters/persister-powersync.d.ts +170 -0
  341. package/lib/types/with-schemas/persisters/persister-remote.d.ts +5 -1
  342. package/lib/types/with-schemas/persisters/persister-sqlite-wasm.d.ts +5 -1
  343. package/lib/types/with-schemas/persisters/persister-sqlite3.d.ts +5 -1
  344. package/lib/types/with-schemas/persisters/persister-yjs.d.ts +7 -3
  345. package/lib/types/with-schemas/persisters.d.ts +161 -101
  346. package/lib/types/with-schemas/queries.d.ts +3 -3
  347. package/lib/types/with-schemas/relationships.d.ts +2 -2
  348. package/lib/types/with-schemas/store.d.ts +483 -345
  349. package/lib/types/with-schemas/synchronizers/synchronizer-local.d.ts +29 -0
  350. package/lib/types/with-schemas/synchronizers/synchronizer-ws-client.d.ts +41 -0
  351. package/lib/types/with-schemas/synchronizers/synchronizer-ws-server.d.ts +36 -0
  352. package/lib/types/with-schemas/synchronizers.d.ts +146 -0
  353. package/lib/types/with-schemas/tinybase.d.ts +9 -8
  354. package/lib/types/with-schemas/tools.d.ts +4 -4
  355. package/lib/types/with-schemas/ui-react.d.ts +259 -102
  356. package/lib/ui-react-dom.js +1 -1
  357. package/lib/ui-react-dom.js.gz +0 -0
  358. package/lib/ui-react.js +1 -1
  359. package/lib/ui-react.js.gz +0 -0
  360. package/lib/umd/checkpoints.js +1 -1
  361. package/lib/umd/checkpoints.js.gz +0 -0
  362. package/lib/umd/indexes.js +1 -1
  363. package/lib/umd/indexes.js.gz +0 -0
  364. package/lib/umd/mergeable-store.js +1 -0
  365. package/lib/umd/mergeable-store.js.gz +0 -0
  366. package/lib/umd/metrics.js +1 -1
  367. package/lib/umd/metrics.js.gz +0 -0
  368. package/lib/umd/persisters/persister-automerge.js +1 -1
  369. package/lib/umd/persisters/persister-automerge.js.gz +0 -0
  370. package/lib/umd/persisters/persister-browser.js +1 -1
  371. package/lib/umd/persisters/persister-browser.js.gz +0 -0
  372. package/lib/umd/persisters/persister-cr-sqlite-wasm.js +1 -1
  373. package/lib/umd/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
  374. package/lib/umd/persisters/persister-electric-sql.js +1 -1
  375. package/lib/umd/persisters/persister-electric-sql.js.gz +0 -0
  376. package/lib/umd/persisters/persister-expo-sqlite-next.js +1 -1
  377. package/lib/umd/persisters/persister-expo-sqlite-next.js.gz +0 -0
  378. package/lib/umd/persisters/persister-expo-sqlite.js +1 -1
  379. package/lib/umd/persisters/persister-expo-sqlite.js.gz +0 -0
  380. package/lib/umd/persisters/persister-file.js +1 -1
  381. package/lib/umd/persisters/persister-file.js.gz +0 -0
  382. package/lib/umd/persisters/persister-indexed-db.js +1 -1
  383. package/lib/umd/persisters/persister-indexed-db.js.gz +0 -0
  384. package/lib/umd/persisters/persister-libsql.js +1 -0
  385. package/lib/umd/persisters/persister-libsql.js.gz +0 -0
  386. package/lib/umd/persisters/persister-partykit-client.js +1 -1
  387. package/lib/umd/persisters/persister-partykit-client.js.gz +0 -0
  388. package/lib/umd/persisters/persister-partykit-server.js +1 -1
  389. package/lib/umd/persisters/persister-partykit-server.js.gz +0 -0
  390. package/lib/umd/persisters/persister-powersync.js +1 -0
  391. package/lib/umd/persisters/persister-powersync.js.gz +0 -0
  392. package/lib/umd/persisters/persister-remote.js +1 -1
  393. package/lib/umd/persisters/persister-remote.js.gz +0 -0
  394. package/lib/umd/persisters/persister-sqlite-wasm.js +1 -1
  395. package/lib/umd/persisters/persister-sqlite-wasm.js.gz +0 -0
  396. package/lib/umd/persisters/persister-sqlite3.js +1 -1
  397. package/lib/umd/persisters/persister-sqlite3.js.gz +0 -0
  398. package/lib/umd/persisters/persister-yjs.js +1 -1
  399. package/lib/umd/persisters/persister-yjs.js.gz +0 -0
  400. package/lib/umd/persisters.js +1 -1
  401. package/lib/umd/persisters.js.gz +0 -0
  402. package/lib/umd/queries.js +1 -1
  403. package/lib/umd/queries.js.gz +0 -0
  404. package/lib/umd/relationships.js +1 -1
  405. package/lib/umd/relationships.js.gz +0 -0
  406. package/lib/umd/store.js +1 -1
  407. package/lib/umd/store.js.gz +0 -0
  408. package/lib/umd/synchronizers/synchronizer-local.js +1 -0
  409. package/lib/umd/synchronizers/synchronizer-local.js.gz +0 -0
  410. package/lib/umd/synchronizers/synchronizer-ws-client.js +1 -0
  411. package/lib/umd/synchronizers/synchronizer-ws-client.js.gz +0 -0
  412. package/lib/umd/synchronizers/synchronizer-ws-server.js +1 -0
  413. package/lib/umd/synchronizers/synchronizer-ws-server.js.gz +0 -0
  414. package/lib/umd/synchronizers.js +1 -0
  415. package/lib/umd/synchronizers.js.gz +0 -0
  416. package/lib/umd/tinybase.js +1 -1
  417. package/lib/umd/tinybase.js.gz +0 -0
  418. package/lib/umd/tools.js +1 -1
  419. package/lib/umd/tools.js.gz +0 -0
  420. package/lib/umd/ui-react-dom-debug.js +1 -1
  421. package/lib/umd/ui-react-dom-debug.js.gz +0 -0
  422. package/lib/umd/ui-react-dom.js +1 -1
  423. package/lib/umd/ui-react-dom.js.gz +0 -0
  424. package/lib/umd/ui-react.js +1 -1
  425. package/lib/umd/ui-react.js.gz +0 -0
  426. package/lib/umd-es6/checkpoints.js +1 -1
  427. package/lib/umd-es6/checkpoints.js.gz +0 -0
  428. package/lib/umd-es6/indexes.js +1 -1
  429. package/lib/umd-es6/indexes.js.gz +0 -0
  430. package/lib/umd-es6/mergeable-store.js +1 -0
  431. package/lib/umd-es6/mergeable-store.js.gz +0 -0
  432. package/lib/umd-es6/metrics.js +1 -1
  433. package/lib/umd-es6/metrics.js.gz +0 -0
  434. package/lib/umd-es6/persisters/persister-automerge.js +1 -1
  435. package/lib/umd-es6/persisters/persister-automerge.js.gz +0 -0
  436. package/lib/umd-es6/persisters/persister-browser.js +1 -1
  437. package/lib/umd-es6/persisters/persister-browser.js.gz +0 -0
  438. package/lib/umd-es6/persisters/persister-cr-sqlite-wasm.js +1 -1
  439. package/lib/umd-es6/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
  440. package/lib/umd-es6/persisters/persister-electric-sql.js +1 -1
  441. package/lib/umd-es6/persisters/persister-electric-sql.js.gz +0 -0
  442. package/lib/umd-es6/persisters/persister-expo-sqlite-next.js +1 -1
  443. package/lib/umd-es6/persisters/persister-expo-sqlite-next.js.gz +0 -0
  444. package/lib/umd-es6/persisters/persister-expo-sqlite.js +1 -1
  445. package/lib/umd-es6/persisters/persister-expo-sqlite.js.gz +0 -0
  446. package/lib/umd-es6/persisters/persister-file.js +1 -1
  447. package/lib/umd-es6/persisters/persister-file.js.gz +0 -0
  448. package/lib/umd-es6/persisters/persister-indexed-db.js +1 -1
  449. package/lib/umd-es6/persisters/persister-indexed-db.js.gz +0 -0
  450. package/lib/umd-es6/persisters/persister-libsql.js +1 -0
  451. package/lib/umd-es6/persisters/persister-libsql.js.gz +0 -0
  452. package/lib/umd-es6/persisters/persister-partykit-client.js +1 -1
  453. package/lib/umd-es6/persisters/persister-partykit-client.js.gz +0 -0
  454. package/lib/umd-es6/persisters/persister-partykit-server.js +1 -1
  455. package/lib/umd-es6/persisters/persister-partykit-server.js.gz +0 -0
  456. package/lib/umd-es6/persisters/persister-powersync.js +1 -0
  457. package/lib/umd-es6/persisters/persister-powersync.js.gz +0 -0
  458. package/lib/umd-es6/persisters/persister-remote.js +1 -1
  459. package/lib/umd-es6/persisters/persister-remote.js.gz +0 -0
  460. package/lib/umd-es6/persisters/persister-sqlite-wasm.js +1 -1
  461. package/lib/umd-es6/persisters/persister-sqlite-wasm.js.gz +0 -0
  462. package/lib/umd-es6/persisters/persister-sqlite3.js +1 -1
  463. package/lib/umd-es6/persisters/persister-sqlite3.js.gz +0 -0
  464. package/lib/umd-es6/persisters/persister-yjs.js +1 -1
  465. package/lib/umd-es6/persisters/persister-yjs.js.gz +0 -0
  466. package/lib/umd-es6/persisters.js +1 -1
  467. package/lib/umd-es6/persisters.js.gz +0 -0
  468. package/lib/umd-es6/queries.js +1 -1
  469. package/lib/umd-es6/queries.js.gz +0 -0
  470. package/lib/umd-es6/relationships.js +1 -1
  471. package/lib/umd-es6/relationships.js.gz +0 -0
  472. package/lib/umd-es6/store.js +1 -1
  473. package/lib/umd-es6/store.js.gz +0 -0
  474. package/lib/umd-es6/synchronizers/synchronizer-local.js +1 -0
  475. package/lib/umd-es6/synchronizers/synchronizer-local.js.gz +0 -0
  476. package/lib/umd-es6/synchronizers/synchronizer-ws-client.js +1 -0
  477. package/lib/umd-es6/synchronizers/synchronizer-ws-client.js.gz +0 -0
  478. package/lib/umd-es6/synchronizers/synchronizer-ws-server.js +1 -0
  479. package/lib/umd-es6/synchronizers/synchronizer-ws-server.js.gz +0 -0
  480. package/lib/umd-es6/synchronizers.js +1 -0
  481. package/lib/umd-es6/synchronizers.js.gz +0 -0
  482. package/lib/umd-es6/tinybase.js +1 -1
  483. package/lib/umd-es6/tinybase.js.gz +0 -0
  484. package/lib/umd-es6/tools.js +1 -1
  485. package/lib/umd-es6/tools.js.gz +0 -0
  486. package/lib/umd-es6/ui-react-dom-debug.js +1 -1
  487. package/lib/umd-es6/ui-react-dom-debug.js.gz +0 -0
  488. package/lib/umd-es6/ui-react-dom.js +1 -1
  489. package/lib/umd-es6/ui-react-dom.js.gz +0 -0
  490. package/lib/umd-es6/ui-react.js +1 -1
  491. package/lib/umd-es6/ui-react.js.gz +0 -0
  492. package/package.json +68 -48
  493. package/readme.md +2 -2
@@ -29,7 +29,11 @@ const VALUE = 'Value';
29
29
  const VALUES = VALUE + 's';
30
30
  const VALUE_IDS = VALUE + IDS;
31
31
  const id = (key) => EMPTY_STRING + key;
32
+ const strStartsWith = (str, prefix) => str.startsWith(prefix);
33
+ const strEndsWith = (str, suffix) => str.endsWith(suffix);
34
+ const strCharCodeAt = (str, position) => str.charCodeAt(position);
32
35
 
36
+ const promise = Promise;
33
37
  const mathMax = Math.max;
34
38
  const mathMin = Math.min;
35
39
  const isFiniteNumber = isFinite;
@@ -45,6 +49,7 @@ const slice = (arrayOrString, start, end) => arrayOrString.slice(start, end);
45
49
  const size = (arrayOrString) => arrayOrString.length;
46
50
  const test = (regex, subject) => regex.test(subject);
47
51
  const getUndefined = () => void 0;
52
+ const promiseNew = (resolver) => new promise(resolver);
48
53
 
49
54
  const arrayHas = (array, value) => array.includes(value);
50
55
  const arrayEvery = (array, cb) => array.every(cb);
@@ -70,9 +75,8 @@ const arrayShift = (array) => array.shift();
70
75
 
71
76
  const object = Object;
72
77
  const getPrototypeOf = (obj) => object.getPrototypeOf(obj);
73
- const objIds = object.keys;
78
+ const objEntries = object.entries;
74
79
  const objFrozen = object.isFrozen;
75
- const objFreeze = object.freeze;
76
80
  const isObject = (obj) =>
77
81
  !isUndefined(obj) &&
78
82
  ifNotUndefined(
@@ -80,18 +84,46 @@ const isObject = (obj) =>
80
84
  (objPrototype) =>
81
85
  objPrototype == object.prototype ||
82
86
  isUndefined(getPrototypeOf(objPrototype)),
87
+ /* istanbul ignore next */
83
88
  () => true,
84
89
  );
85
- const objGet = (obj, id) => ifNotUndefined(obj, (obj2) => obj2[id]);
86
- const objHas = (obj, id) => !isUndefined(objGet(obj, id));
90
+ const objIds = object.keys;
91
+ const objFreeze = object.freeze;
92
+ const objNew = (entries = []) => object.fromEntries(entries);
93
+ const objHas = (obj, id) => id in obj;
87
94
  const objDel = (obj, id) => {
88
95
  delete obj[id];
89
96
  return obj;
90
97
  };
91
- const objMap = (obj, cb) =>
92
- arrayMap(object.entries(obj), ([id, value]) => cb(value, id));
98
+ const objForEach = (obj, cb) =>
99
+ arrayForEach(objEntries(obj), ([id, value]) => cb(value, id));
100
+ const objToArray = (obj, cb) =>
101
+ arrayMap(objEntries(obj), ([id, value]) => cb(value, id));
93
102
  const objSize = (obj) => size(objIds(obj));
94
103
  const objIsEmpty = (obj) => isObject(obj) && objSize(obj) == 0;
104
+ const objEnsure = (obj, id, getDefaultValue) => {
105
+ if (!objHas(obj, id)) {
106
+ obj[id] = getDefaultValue();
107
+ }
108
+ return obj[id];
109
+ };
110
+ const objValidate = (obj, validateChild, onInvalidObj, emptyIsValid = 0) => {
111
+ if (
112
+ isUndefined(obj) ||
113
+ !isObject(obj) ||
114
+ (!emptyIsValid && objIsEmpty(obj)) ||
115
+ objFrozen(obj)
116
+ ) {
117
+ onInvalidObj?.();
118
+ return false;
119
+ }
120
+ objToArray(obj, (child, id) => {
121
+ if (!validateChild(child, id)) {
122
+ objDel(obj, id);
123
+ }
124
+ });
125
+ return emptyIsValid ? true : !objIsEmpty(obj);
126
+ };
95
127
 
96
128
  const collSizeN = (collSizer) => (coll) =>
97
129
  arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
@@ -115,35 +147,41 @@ const mapMap = (coll, cb) =>
115
147
  arrayMap([...(coll?.entries() ?? [])], ([key, value]) => cb(value, key));
116
148
  const mapSet = (map, key, value) =>
117
149
  isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
118
- const mapEnsure = (map, key, getDefaultValue) => {
150
+ const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
119
151
  if (!collHas(map, key)) {
120
152
  mapSet(map, key, getDefaultValue());
153
+ } else {
154
+ hadExistingValue?.(mapGet(map, key));
121
155
  }
122
156
  return mapGet(map, key);
123
157
  };
124
158
  const mapMatch = (map, obj, set, del = mapSet) => {
125
- objMap(obj, (value, id) => set(map, id, value));
159
+ objToArray(obj, (value, id) => set(map, id, value));
126
160
  mapForEach(map, (id) => (objHas(obj, id) ? 0 : del(map, id)));
127
161
  return map;
128
162
  };
129
- const mapToObj = (map, mapValue, excludeValue) => {
163
+ const mapToObj = (map, valueMapper, excludeMapValue, excludeObjValue) => {
130
164
  const obj = {};
131
- collForEach(map, (value, id) => {
132
- const mappedValue = mapValue ? mapValue(value, id) : value;
133
- excludeValue?.(mappedValue, value) ? 0 : (obj[id] = mappedValue);
165
+ collForEach(map, (mapValue, id) => {
166
+ if (!excludeMapValue?.(mapValue, id)) {
167
+ const objValue = valueMapper ? valueMapper(mapValue, id) : mapValue;
168
+ excludeObjValue?.(objValue) ? 0 : (obj[id] = objValue);
169
+ }
134
170
  });
135
171
  return obj;
136
172
  };
137
- const mapToObj2 = (map, mapValue, excludeValue) =>
173
+ const mapToObj2 = (map, valueMapper, excludeMapValue) =>
138
174
  mapToObj(
139
175
  map,
140
- (childMap) => mapToObj(childMap, mapValue, excludeValue),
176
+ (childMap) => mapToObj(childMap, valueMapper, excludeMapValue),
177
+ collIsEmpty,
141
178
  objIsEmpty,
142
179
  );
143
- const mapToObj3 = (map, mapValue, excludeValue) =>
180
+ const mapToObj3 = (map, valueMapper, excludeMapValue) =>
144
181
  mapToObj(
145
182
  map,
146
- (childMap) => mapToObj2(childMap, mapValue, excludeValue),
183
+ (childMap) => mapToObj2(childMap, valueMapper, excludeMapValue),
184
+ collIsEmpty,
147
185
  objIsEmpty,
148
186
  );
149
187
  const mapClone = (map, mapValue) => {
@@ -175,12 +213,15 @@ const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
175
213
  },
176
214
  );
177
215
 
178
- const getCellOrValueType = (cell) => {
179
- const type = getTypeOf(cell);
180
- return isTypeStringOrBoolean(type) || (type == NUMBER && isFiniteNumber(cell))
216
+ const getCellOrValueType = (cellOrValue) => {
217
+ const type = getTypeOf(cellOrValue);
218
+ return isTypeStringOrBoolean(type) ||
219
+ (type == NUMBER && isFiniteNumber(cellOrValue))
181
220
  ? type
182
221
  : void 0;
183
222
  };
223
+ const isCellOrValueOrNullOrUndefined = (cellOrValue) =>
224
+ isUndefined(cellOrValue) || !isUndefined(getCellOrValueType(cellOrValue));
184
225
  const setOrDelCell = (store, tableId, rowId, cellId, cell) =>
185
226
  isUndefined(cell)
186
227
  ? store.delCell(tableId, rowId, cellId, true)
@@ -356,13 +397,15 @@ const getRowCellFunction = (getRowCell, defaultCellValue) =>
356
397
  isString(getRowCell)
357
398
  ? (getCell) => getCell(getRowCell)
358
399
  : getRowCell ?? (() => defaultCellValue ?? EMPTY_STRING);
359
- const getCreateFunction = (getFunction) => {
360
- const getFunctionsByStore = /* @__PURE__ */ new WeakMap();
400
+ const getCreateFunction = (getFunction, initFunction) => {
401
+ const thingsByStore = /* @__PURE__ */ new WeakMap();
361
402
  return (store) => {
362
- if (!getFunctionsByStore.has(store)) {
363
- getFunctionsByStore.set(store, getFunction(store));
403
+ if (!thingsByStore.has(store)) {
404
+ thingsByStore.set(store, getFunction(store));
364
405
  }
365
- return getFunctionsByStore.get(store);
406
+ const thing = thingsByStore.get(store);
407
+ initFunction?.(thing);
408
+ return thing;
366
409
  };
367
410
  };
368
411
 
@@ -450,241 +493,256 @@ const getListenerFunctions = (getThing) => {
450
493
  return [addListener, callListeners, delListener, callListener];
451
494
  };
452
495
 
453
- const createCheckpoints = getCreateFunction((store) => {
454
- let backwardIdsSize = 100;
455
- let currentId;
456
- let cellsDelta = mapNew();
457
- let valuesDelta = mapNew();
458
- let listening = 1;
459
- let nextCheckpointId;
460
- let checkpointsChanged;
461
- const checkpointIdsListeners = mapNew();
462
- const checkpointListeners = mapNew();
463
- const [addListener, callListeners, delListenerImpl] = getListenerFunctions(
464
- () => checkpoints,
465
- );
466
- const deltas = mapNew();
467
- const labels = mapNew();
468
- const backwardIds = [];
469
- const forwardIds = [];
470
- const updateStore = (oldOrNew, checkpointId) => {
471
- listening = 0;
472
- store.transaction(() => {
473
- const [cellsDelta2, valuesDelta2] = mapGet(deltas, checkpointId);
474
- collForEach(cellsDelta2, (table, tableId) =>
475
- collForEach(table, (row, rowId) =>
476
- collForEach(row, (oldNew, cellId) =>
477
- setOrDelCell(store, tableId, rowId, cellId, oldNew[oldOrNew]),
496
+ const createCheckpoints = getCreateFunction(
497
+ (store) => {
498
+ let backwardIdsSize = 100;
499
+ let currentId;
500
+ let cellsDelta = mapNew();
501
+ let valuesDelta = mapNew();
502
+ let listening = 1;
503
+ let nextCheckpointId;
504
+ let checkpointsChanged;
505
+ const checkpointIdsListeners = mapNew();
506
+ const checkpointListeners = mapNew();
507
+ const [addListener, callListeners, delListenerImpl] = getListenerFunctions(
508
+ () => checkpoints,
509
+ );
510
+ const deltas = mapNew();
511
+ const labels = mapNew();
512
+ const backwardIds = [];
513
+ const forwardIds = [];
514
+ const updateStore = (oldOrNew, checkpointId) => {
515
+ listening = 0;
516
+ store.transaction(() => {
517
+ const [cellsDelta2, valuesDelta2] = mapGet(deltas, checkpointId);
518
+ collForEach(cellsDelta2, (table, tableId) =>
519
+ collForEach(table, (row, rowId) =>
520
+ collForEach(row, (oldNew, cellId) =>
521
+ setOrDelCell(store, tableId, rowId, cellId, oldNew[oldOrNew]),
522
+ ),
478
523
  ),
479
- ),
480
- );
481
- collForEach(valuesDelta2, (oldNew, valueId) =>
482
- setOrDelValue(store, valueId, oldNew[oldOrNew]),
524
+ );
525
+ collForEach(valuesDelta2, (oldNew, valueId) =>
526
+ setOrDelValue(store, valueId, oldNew[oldOrNew]),
527
+ );
528
+ });
529
+ listening = 1;
530
+ };
531
+ const clearCheckpointId = (checkpointId) => {
532
+ mapSet(deltas, checkpointId);
533
+ mapSet(labels, checkpointId);
534
+ callListeners(checkpointListeners, [checkpointId]);
535
+ };
536
+ const clearCheckpointIds = (checkpointIds, to) =>
537
+ arrayForEach(
538
+ arrayClear(checkpointIds, to ?? size(checkpointIds)),
539
+ clearCheckpointId,
483
540
  );
484
- });
485
- listening = 1;
486
- };
487
- const clearCheckpointId = (checkpointId) => {
488
- mapSet(deltas, checkpointId);
489
- mapSet(labels, checkpointId);
490
- callListeners(checkpointListeners, [checkpointId]);
491
- };
492
- const clearCheckpointIds = (checkpointIds, to) =>
493
- arrayForEach(
494
- arrayClear(checkpointIds, to ?? size(checkpointIds)),
495
- clearCheckpointId,
496
- );
497
- const trimBackwardsIds = () =>
498
- clearCheckpointIds(backwardIds, size(backwardIds) - backwardIdsSize);
499
- const storeChanged = () =>
500
- ifNotUndefined(currentId, () => {
501
- arrayPush(backwardIds, currentId);
502
- trimBackwardsIds();
503
- clearCheckpointIds(forwardIds);
504
- currentId = void 0;
541
+ const trimBackwardsIds = () =>
542
+ clearCheckpointIds(backwardIds, size(backwardIds) - backwardIdsSize);
543
+ const storeChanged = () =>
544
+ ifNotUndefined(currentId, () => {
545
+ arrayPush(backwardIds, currentId);
546
+ trimBackwardsIds();
547
+ clearCheckpointIds(forwardIds);
548
+ currentId = void 0;
549
+ checkpointsChanged = 1;
550
+ });
551
+ const storeUnchanged = () => {
552
+ currentId = arrayPop(backwardIds);
505
553
  checkpointsChanged = 1;
506
- });
507
- const storeUnchanged = () => {
508
- currentId = arrayPop(backwardIds);
509
- checkpointsChanged = 1;
510
- };
511
- const cellListenerId = store.addCellListener(
512
- null,
513
- null,
514
- null,
515
- (_store, tableId, rowId, cellId, newCell, oldCell) => {
516
- if (listening) {
517
- storeChanged();
518
- const table = mapEnsure(cellsDelta, tableId, mapNew);
519
- const row = mapEnsure(table, rowId, mapNew);
520
- const oldNew = mapEnsure(row, cellId, () => [oldCell, void 0]);
521
- oldNew[1] = newCell;
522
- if (
523
- oldNew[0] === newCell &&
524
- collIsEmpty(mapSet(row, cellId)) &&
525
- collIsEmpty(mapSet(table, rowId)) &&
526
- collIsEmpty(mapSet(cellsDelta, tableId))
527
- ) {
528
- storeUnchanged();
529
- }
530
- callListenersIfChanged();
554
+ };
555
+ let cellListenerId;
556
+ let valueListenerId;
557
+ const addCheckpointImpl = (label = EMPTY_STRING) => {
558
+ if (isUndefined(currentId)) {
559
+ currentId = EMPTY_STRING + nextCheckpointId++;
560
+ mapSet(deltas, currentId, [cellsDelta, valuesDelta]);
561
+ setCheckpoint(currentId, label);
562
+ cellsDelta = mapNew();
563
+ valuesDelta = mapNew();
564
+ checkpointsChanged = 1;
531
565
  }
532
- },
533
- );
534
- const valueListenerId = store.addValueListener(
535
- null,
536
- (_store, valueId, newValue, oldValue) => {
537
- if (listening) {
538
- storeChanged();
539
- const oldNew = mapEnsure(valuesDelta, valueId, () => [
540
- oldValue,
541
- void 0,
542
- ]);
543
- oldNew[1] = newValue;
544
- if (
545
- oldNew[0] === newValue &&
546
- collIsEmpty(mapSet(valuesDelta, valueId))
547
- ) {
548
- storeUnchanged();
549
- }
550
- callListenersIfChanged();
566
+ return currentId;
567
+ };
568
+ const goBackwardImpl = () => {
569
+ if (!arrayIsEmpty(backwardIds)) {
570
+ arrayUnshift(forwardIds, addCheckpointImpl());
571
+ updateStore(0, currentId);
572
+ currentId = arrayPop(backwardIds);
573
+ checkpointsChanged = 1;
551
574
  }
552
- },
553
- );
554
- const addCheckpointImpl = (label = EMPTY_STRING) => {
555
- if (isUndefined(currentId)) {
556
- currentId = EMPTY_STRING + nextCheckpointId++;
557
- mapSet(deltas, currentId, [cellsDelta, valuesDelta]);
558
- setCheckpoint(currentId, label);
559
- cellsDelta = mapNew();
560
- valuesDelta = mapNew();
561
- checkpointsChanged = 1;
562
- }
563
- return currentId;
564
- };
565
- const goBackwardImpl = () => {
566
- if (!arrayIsEmpty(backwardIds)) {
567
- arrayUnshift(forwardIds, addCheckpointImpl());
568
- updateStore(0, currentId);
569
- currentId = arrayPop(backwardIds);
570
- checkpointsChanged = 1;
571
- }
572
- };
573
- const goForwardImpl = () => {
574
- if (!arrayIsEmpty(forwardIds)) {
575
- arrayPush(backwardIds, currentId);
576
- currentId = arrayShift(forwardIds);
577
- updateStore(1, currentId);
578
- checkpointsChanged = 1;
579
- }
580
- };
581
- const callListenersIfChanged = () => {
582
- if (checkpointsChanged) {
583
- callListeners(checkpointIdsListeners);
584
- checkpointsChanged = 0;
585
- }
586
- };
587
- const setSize = (size2) => {
588
- backwardIdsSize = size2;
589
- trimBackwardsIds();
590
- return checkpoints;
591
- };
592
- const addCheckpoint = (label) => {
593
- const id = addCheckpointImpl(label);
594
- callListenersIfChanged();
595
- return id;
596
- };
597
- const setCheckpoint = (checkpointId, label) => {
598
- if (hasCheckpoint(checkpointId) && mapGet(labels, checkpointId) !== label) {
599
- mapSet(labels, checkpointId, label);
600
- callListeners(checkpointListeners, [checkpointId]);
601
- }
602
- return checkpoints;
603
- };
604
- const getStore = () => store;
605
- const getCheckpointIds = () => [[...backwardIds], currentId, [...forwardIds]];
606
- const forEachCheckpoint = (checkpointCallback) =>
607
- mapForEach(labels, checkpointCallback);
608
- const hasCheckpoint = (checkpointId) => collHas(deltas, checkpointId);
609
- const getCheckpoint = (checkpointId) => mapGet(labels, checkpointId);
610
- const goBackward = () => {
611
- goBackwardImpl();
612
- callListenersIfChanged();
613
- return checkpoints;
614
- };
615
- const goForward = () => {
616
- goForwardImpl();
617
- callListenersIfChanged();
618
- return checkpoints;
619
- };
620
- const goTo = (checkpointId) => {
621
- const action = arrayHas(backwardIds, checkpointId)
622
- ? goBackwardImpl
623
- : arrayHas(forwardIds, checkpointId)
624
- ? goForwardImpl
625
- : null;
626
- while (!isUndefined(action) && checkpointId != currentId) {
627
- action();
628
- }
629
- callListenersIfChanged();
630
- return checkpoints;
631
- };
632
- const addCheckpointIdsListener = (listener) =>
633
- addListener(listener, checkpointIdsListeners);
634
- const addCheckpointListener = (checkpointId, listener) =>
635
- addListener(listener, checkpointListeners, [checkpointId]);
636
- const delListener = (listenerId) => {
637
- delListenerImpl(listenerId);
638
- return checkpoints;
639
- };
640
- const clear = () => {
641
- clearCheckpointIds(backwardIds);
642
- clearCheckpointIds(forwardIds);
643
- if (!isUndefined(currentId)) {
644
- clearCheckpointId(currentId);
645
- }
646
- currentId = void 0;
647
- nextCheckpointId = 0;
648
- addCheckpoint();
649
- return checkpoints;
650
- };
651
- const clearForward = () => {
652
- if (!arrayIsEmpty(forwardIds)) {
575
+ };
576
+ const goForwardImpl = () => {
577
+ if (!arrayIsEmpty(forwardIds)) {
578
+ arrayPush(backwardIds, currentId);
579
+ currentId = arrayShift(forwardIds);
580
+ updateStore(1, currentId);
581
+ checkpointsChanged = 1;
582
+ }
583
+ };
584
+ const callListenersIfChanged = () => {
585
+ if (checkpointsChanged) {
586
+ callListeners(checkpointIdsListeners);
587
+ checkpointsChanged = 0;
588
+ }
589
+ };
590
+ const setSize = (size2) => {
591
+ backwardIdsSize = size2;
592
+ trimBackwardsIds();
593
+ return checkpoints;
594
+ };
595
+ const addCheckpoint = (label) => {
596
+ const id = addCheckpointImpl(label);
597
+ callListenersIfChanged();
598
+ return id;
599
+ };
600
+ const setCheckpoint = (checkpointId, label) => {
601
+ if (
602
+ hasCheckpoint(checkpointId) &&
603
+ mapGet(labels, checkpointId) !== label
604
+ ) {
605
+ mapSet(labels, checkpointId, label);
606
+ callListeners(checkpointListeners, [checkpointId]);
607
+ }
608
+ return checkpoints;
609
+ };
610
+ const getStore = () => store;
611
+ const getCheckpointIds = () => [
612
+ [...backwardIds],
613
+ currentId,
614
+ [...forwardIds],
615
+ ];
616
+ const forEachCheckpoint = (checkpointCallback) =>
617
+ mapForEach(labels, checkpointCallback);
618
+ const hasCheckpoint = (checkpointId) => collHas(deltas, checkpointId);
619
+ const getCheckpoint = (checkpointId) => mapGet(labels, checkpointId);
620
+ const goBackward = () => {
621
+ goBackwardImpl();
622
+ callListenersIfChanged();
623
+ return checkpoints;
624
+ };
625
+ const goForward = () => {
626
+ goForwardImpl();
627
+ callListenersIfChanged();
628
+ return checkpoints;
629
+ };
630
+ const goTo = (checkpointId) => {
631
+ const action = arrayHas(backwardIds, checkpointId)
632
+ ? goBackwardImpl
633
+ : arrayHas(forwardIds, checkpointId)
634
+ ? goForwardImpl
635
+ : null;
636
+ while (!isUndefined(action) && checkpointId != currentId) {
637
+ action();
638
+ }
639
+ callListenersIfChanged();
640
+ return checkpoints;
641
+ };
642
+ const addCheckpointIdsListener = (listener) =>
643
+ addListener(listener, checkpointIdsListeners);
644
+ const addCheckpointListener = (checkpointId, listener) =>
645
+ addListener(listener, checkpointListeners, [checkpointId]);
646
+ const delListener = (listenerId) => {
647
+ delListenerImpl(listenerId);
648
+ return checkpoints;
649
+ };
650
+ const clear = () => {
651
+ clearCheckpointIds(backwardIds);
653
652
  clearCheckpointIds(forwardIds);
654
- callListeners(checkpointIdsListeners);
655
- }
656
- return checkpoints;
657
- };
658
- const destroy = () => {
659
- store.delListener(cellListenerId);
660
- store.delListener(valueListenerId);
661
- };
662
- const getListenerStats = () => ({
663
- checkpointIds: collSize2(checkpointIdsListeners),
664
- checkpoint: collSize2(checkpointListeners),
665
- });
666
- const checkpoints = {
667
- setSize,
668
- addCheckpoint,
669
- setCheckpoint,
670
- getStore,
671
- getCheckpointIds,
672
- forEachCheckpoint,
673
- hasCheckpoint,
674
- getCheckpoint,
675
- goBackward,
676
- goForward,
677
- goTo,
678
- addCheckpointIdsListener,
679
- addCheckpointListener,
680
- delListener,
681
- clear,
682
- clearForward,
683
- destroy,
684
- getListenerStats,
685
- };
686
- return objFreeze(checkpoints.clear());
687
- });
653
+ if (!isUndefined(currentId)) {
654
+ clearCheckpointId(currentId);
655
+ }
656
+ currentId = void 0;
657
+ nextCheckpointId = 0;
658
+ addCheckpoint();
659
+ return checkpoints;
660
+ };
661
+ const clearForward = () => {
662
+ if (!arrayIsEmpty(forwardIds)) {
663
+ clearCheckpointIds(forwardIds);
664
+ callListeners(checkpointIdsListeners);
665
+ }
666
+ return checkpoints;
667
+ };
668
+ const destroy = () => {
669
+ store.delListener(cellListenerId);
670
+ store.delListener(valueListenerId);
671
+ };
672
+ const getListenerStats = () => ({
673
+ checkpointIds: collSize2(checkpointIdsListeners),
674
+ checkpoint: collSize2(checkpointListeners),
675
+ });
676
+ const _registerListeners = () => {
677
+ cellListenerId = store.addCellListener(
678
+ null,
679
+ null,
680
+ null,
681
+ (_store, tableId, rowId, cellId, newCell, oldCell) => {
682
+ if (listening) {
683
+ storeChanged();
684
+ const table = mapEnsure(cellsDelta, tableId, mapNew);
685
+ const row = mapEnsure(table, rowId, mapNew);
686
+ const oldNew = mapEnsure(row, cellId, () => [oldCell, void 0]);
687
+ oldNew[1] = newCell;
688
+ if (
689
+ oldNew[0] === newCell &&
690
+ collIsEmpty(mapSet(row, cellId)) &&
691
+ collIsEmpty(mapSet(table, rowId)) &&
692
+ collIsEmpty(mapSet(cellsDelta, tableId))
693
+ ) {
694
+ storeUnchanged();
695
+ }
696
+ callListenersIfChanged();
697
+ }
698
+ },
699
+ );
700
+ valueListenerId = store.addValueListener(
701
+ null,
702
+ (_store, valueId, newValue, oldValue) => {
703
+ if (listening) {
704
+ storeChanged();
705
+ const oldNew = mapEnsure(valuesDelta, valueId, () => [
706
+ oldValue,
707
+ void 0,
708
+ ]);
709
+ oldNew[1] = newValue;
710
+ if (
711
+ oldNew[0] === newValue &&
712
+ collIsEmpty(mapSet(valuesDelta, valueId))
713
+ ) {
714
+ storeUnchanged();
715
+ }
716
+ callListenersIfChanged();
717
+ }
718
+ },
719
+ );
720
+ };
721
+ const checkpoints = {
722
+ setSize,
723
+ addCheckpoint,
724
+ setCheckpoint,
725
+ getStore,
726
+ getCheckpointIds,
727
+ forEachCheckpoint,
728
+ hasCheckpoint,
729
+ getCheckpoint,
730
+ goBackward,
731
+ goForward,
732
+ goTo,
733
+ addCheckpointIdsListener,
734
+ addCheckpointListener,
735
+ delListener,
736
+ clear,
737
+ clearForward,
738
+ destroy,
739
+ getListenerStats,
740
+ _registerListeners,
741
+ };
742
+ return objFreeze(checkpoints.clear());
743
+ },
744
+ (checkpoints) => checkpoints._registerListeners(),
745
+ );
688
746
 
689
747
  const defaultSorter = (sortKey1, sortKey2) =>
690
748
  (sortKey1 ?? 0) < (sortKey2 ?? 0) ? -1 : 1;
@@ -1060,6 +1118,24 @@ const createMetrics = getCreateFunction((store) => {
1060
1118
 
1061
1119
  const scheduleRunning = mapNew();
1062
1120
  const scheduleActions = mapNew();
1121
+ const getStoreFunctions = (supportsMergeableStore, store) =>
1122
+ !supportsMergeableStore || isUndefined(store.getMergeableContent)
1123
+ ? [
1124
+ 0,
1125
+ store.getContent,
1126
+ store.getTransactionChanges,
1127
+ ([changedTables, changedValues]) =>
1128
+ !objIsEmpty(changedTables) || !objIsEmpty(changedValues),
1129
+ store.setContent,
1130
+ ]
1131
+ : [
1132
+ 1,
1133
+ store.getMergeableContent,
1134
+ store.getTransactionMergeableChanges,
1135
+ ([[changedTables], [changedValues]]) =>
1136
+ !objIsEmpty(changedTables) || !objIsEmpty(changedValues),
1137
+ store.setDefaultContent,
1138
+ ];
1063
1139
  const createCustomPersister = (
1064
1140
  store,
1065
1141
  getPersisted,
@@ -1067,18 +1143,25 @@ const createCustomPersister = (
1067
1143
  addPersisterListener,
1068
1144
  delPersisterListener,
1069
1145
  onIgnoredError,
1070
- [getThing, thing] = [],
1146
+ supportsMergeableStore,
1147
+ extra = {},
1071
1148
  scheduleId = [],
1072
1149
  ) => {
1073
- let listenerId;
1074
1150
  let loadSave = 0;
1075
1151
  let loads = 0;
1076
1152
  let saves = 0;
1077
- let listening = 0;
1078
1153
  let action;
1079
- let listeningHandle;
1154
+ let autoLoadHandle;
1155
+ let autoSaveListenerId;
1080
1156
  mapEnsure(scheduleRunning, scheduleId, () => 0);
1081
1157
  mapEnsure(scheduleActions, scheduleId, () => []);
1158
+ const [
1159
+ isMergeableStore,
1160
+ getContent,
1161
+ getChanges,
1162
+ hasChanges,
1163
+ setDefaultContent,
1164
+ ] = getStoreFunctions(supportsMergeableStore, store);
1082
1165
  const run = async () => {
1083
1166
  /* istanbul ignore else */
1084
1167
  if (!mapGet(scheduleRunning, scheduleId)) {
@@ -1110,48 +1193,54 @@ const createCustomPersister = (
1110
1193
  }
1111
1194
  return persister;
1112
1195
  };
1196
+ const setContentOrChanges = (contentOrChanges) => {
1197
+ (isMergeableStore && isArray(contentOrChanges?.[0])
1198
+ ? contentOrChanges?.[2] === 1
1199
+ ? store.applyMergeableChanges
1200
+ : store.setMergeableContent
1201
+ : contentOrChanges?.[2] === 1
1202
+ ? store.applyChanges
1203
+ : store.setContent)(contentOrChanges);
1204
+ };
1113
1205
  const persister = {
1114
- load: async (initialTables, initialValues) =>
1206
+ load: async (initialContent) =>
1115
1207
  await loadLock(async () => {
1116
1208
  try {
1117
- store.setContent(await getPersisted());
1118
- } catch {
1119
- store.setContent([initialTables, initialValues]);
1209
+ setContentOrChanges(await getPersisted());
1210
+ } catch (error) {
1211
+ onIgnoredError?.(error);
1212
+ if (initialContent) {
1213
+ setDefaultContent(initialContent);
1214
+ }
1120
1215
  }
1121
1216
  }),
1122
- startAutoLoad: async (initialTables = {}, initialValues = {}) => {
1123
- persister.stopAutoLoad();
1124
- await persister.load(initialTables, initialValues);
1125
- listening = 1;
1126
- listeningHandle = addPersisterListener(
1127
- async (getContent, getTransactionChanges) => {
1128
- if (getTransactionChanges) {
1129
- const transactionChanges = getTransactionChanges();
1130
- await loadLock(async () =>
1131
- store.setTransactionChanges(transactionChanges),
1132
- );
1133
- } else {
1134
- await loadLock(async () => {
1135
- try {
1136
- store.setContent(getContent?.() ?? (await getPersisted()));
1137
- } catch (error) {
1138
- onIgnoredError?.(error);
1139
- }
1140
- });
1141
- }
1217
+ startAutoLoad: async (initialContent) => {
1218
+ await persister.stopAutoLoad().load(initialContent);
1219
+ autoLoadHandle = addPersisterListener(
1220
+ async (getContent2, getChanges2) => {
1221
+ const changes = getChanges2?.();
1222
+ await loadLock(async () => {
1223
+ try {
1224
+ setContentOrChanges(
1225
+ changes ?? getContent2?.() ?? (await getPersisted()),
1226
+ );
1227
+ } catch (error) {
1228
+ onIgnoredError?.(error);
1229
+ }
1230
+ });
1142
1231
  },
1143
1232
  );
1144
1233
  return persister;
1145
1234
  },
1146
1235
  stopAutoLoad: () => {
1147
- if (listening) {
1148
- delPersisterListener(listeningHandle);
1149
- listeningHandle = void 0;
1150
- listening = 0;
1236
+ if (autoLoadHandle) {
1237
+ delPersisterListener(autoLoadHandle);
1238
+ autoLoadHandle = void 0;
1151
1239
  }
1152
1240
  return persister;
1153
1241
  },
1154
- save: async (getTransactionChanges) => {
1242
+ isAutoLoading: () => !isUndefined(autoLoadHandle),
1243
+ save: async (getChanges2) => {
1155
1244
  /* istanbul ignore else */
1156
1245
  if (loadSave != 1) {
1157
1246
  loadSave = 2;
@@ -1160,7 +1249,7 @@ const createCustomPersister = (
1160
1249
  }
1161
1250
  await persister.schedule(async () => {
1162
1251
  try {
1163
- await setPersisted(store.getContent, getTransactionChanges);
1252
+ await setPersisted(getContent, getChanges2);
1164
1253
  } catch (error) {
1165
1254
  /* istanbul ignore next */
1166
1255
  onIgnoredError?.(error);
@@ -1172,21 +1261,20 @@ const createCustomPersister = (
1172
1261
  },
1173
1262
  startAutoSave: async () => {
1174
1263
  await persister.stopAutoSave().save();
1175
- listenerId = store.addDidFinishTransactionListener(
1176
- (_store, getTransactionChanges) => {
1177
- const [tableChanges, valueChanges] = getTransactionChanges();
1178
- if (!objIsEmpty(tableChanges) || !objIsEmpty(valueChanges)) {
1179
- persister.save(() => [tableChanges, valueChanges]);
1180
- }
1181
- },
1182
- );
1264
+ autoSaveListenerId = store.addDidFinishTransactionListener(() => {
1265
+ const changes = getChanges();
1266
+ if (hasChanges(changes)) {
1267
+ persister.save(() => changes);
1268
+ }
1269
+ });
1183
1270
  return persister;
1184
1271
  },
1185
1272
  stopAutoSave: () => {
1186
- ifNotUndefined(listenerId, store.delListener);
1187
- listenerId = void 0;
1273
+ ifNotUndefined(autoSaveListenerId, store.delListener);
1274
+ autoSaveListenerId = void 0;
1188
1275
  return persister;
1189
1276
  },
1277
+ isAutoSaving: () => !isUndefined(autoSaveListenerId),
1190
1278
  schedule: async (...actions) => {
1191
1279
  arrayPush(mapGet(scheduleActions, scheduleId), ...actions);
1192
1280
  await run();
@@ -1195,13 +1283,325 @@ const createCustomPersister = (
1195
1283
  getStore: () => store,
1196
1284
  destroy: () => persister.stopAutoLoad().stopAutoSave(),
1197
1285
  getStats: () => ({loads, saves}),
1286
+ ...extra,
1198
1287
  };
1199
- if (getThing) {
1200
- persister[getThing] = () => thing;
1201
- }
1202
1288
  return objFreeze(persister);
1203
1289
  };
1204
1290
 
1291
+ const textEncoder = new globalThis.TextEncoder();
1292
+ const getHash = (value) => {
1293
+ let hash = 2166136261;
1294
+ arrayForEach(textEncoder.encode(value), (char) => {
1295
+ hash ^= char;
1296
+ hash +=
1297
+ (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
1298
+ });
1299
+ return hash >>> 0;
1300
+ };
1301
+
1302
+ const stampCloneWithHash = ([value, time, hash]) => [value, time, hash];
1303
+ const stampCloneWithoutHash = ([value, time]) => newStamp(value, time);
1304
+ const newStamp = (value, time) => (time ? [value, time] : [value]);
1305
+ const getStampHash = (stamp) => stamp[2];
1306
+ const hashIdAndHash = (id, hash) => getHash(id + ':' + hash);
1307
+ const replaceTimeHash = (oldTime, newTime) =>
1308
+ newTime > oldTime ? (oldTime ? getHash(oldTime) : 0) ^ getHash(newTime) : 0;
1309
+ const getLatestTime = (time1, time2) =>
1310
+ ((time1 ?? '') > (time2 ?? '') ? time1 : time2) ?? '';
1311
+ const stampUpdate = (stamp, hash, time) => {
1312
+ stamp[2] = hash >>> 0;
1313
+ if (time > stamp[1]) {
1314
+ stamp[1] = time;
1315
+ }
1316
+ };
1317
+ const stampNewObj = (time = EMPTY_STRING) => newStamp(objNew(), time);
1318
+ const stampNewMap = (time = EMPTY_STRING) => [mapNew(), time, 0];
1319
+ const stampMapToObjWithHash = (
1320
+ [map, time, hash],
1321
+ mapper = stampCloneWithHash,
1322
+ ) => [mapToObj(map, mapper), time, hash];
1323
+ const stampMapToObjWithoutHash = (
1324
+ [map, time],
1325
+ mapper = stampCloneWithoutHash,
1326
+ ) => newStamp(mapToObj(map, mapper), time);
1327
+ const stampValidate = (stamp, validateThing) =>
1328
+ isArray(stamp) &&
1329
+ size(stamp) == 3 &&
1330
+ isString(stamp[1]) &&
1331
+ getTypeOf(stamp[2]) == NUMBER &&
1332
+ isFiniteNumber(stamp[2]) &&
1333
+ validateThing(stamp[0]);
1334
+
1335
+ const MASK6 = 63;
1336
+ const SHIFT36 = 2 ** 36;
1337
+ const SHIFT30 = 2 ** 30;
1338
+ const SHIFT24 = 2 ** 24;
1339
+ const SHIFT18 = 2 ** 18;
1340
+ const SHIFT12 = 2 ** 12;
1341
+ const SHIFT6 = 2 ** 6;
1342
+ const toB64 = (num) => String.fromCharCode(48 + (num & MASK6));
1343
+ const fromB64 = (str, pos) => strCharCodeAt(str, pos) - 48;
1344
+ const encodeHlc = (logicalTime42, counter24, clientHash30) =>
1345
+ toB64(logicalTime42 / SHIFT36) +
1346
+ toB64(logicalTime42 / SHIFT30) +
1347
+ toB64(logicalTime42 / SHIFT24) +
1348
+ toB64(logicalTime42 / SHIFT18) +
1349
+ toB64(logicalTime42 / SHIFT12) +
1350
+ toB64(logicalTime42 / SHIFT6) +
1351
+ toB64(logicalTime42) +
1352
+ toB64(counter24 / SHIFT18) +
1353
+ toB64(counter24 / SHIFT12) +
1354
+ toB64(counter24 / SHIFT6) +
1355
+ toB64(counter24) +
1356
+ toB64(clientHash30 / SHIFT24) +
1357
+ toB64(clientHash30 / SHIFT18) +
1358
+ toB64(clientHash30 / SHIFT12) +
1359
+ toB64(clientHash30 / SHIFT6) +
1360
+ toB64(clientHash30);
1361
+ const decodeHlc = (hlc16) => [
1362
+ fromB64(hlc16, 0) * SHIFT36 +
1363
+ fromB64(hlc16, 1) * SHIFT30 +
1364
+ fromB64(hlc16, 2) * SHIFT24 +
1365
+ fromB64(hlc16, 3) * SHIFT18 +
1366
+ fromB64(hlc16, 4) * SHIFT12 +
1367
+ fromB64(hlc16, 5) * SHIFT6 +
1368
+ fromB64(hlc16, 6),
1369
+ fromB64(hlc16, 7) * SHIFT18 +
1370
+ fromB64(hlc16, 8) * SHIFT12 +
1371
+ fromB64(hlc16, 9) * SHIFT6 +
1372
+ fromB64(hlc16, 10),
1373
+ fromB64(hlc16, 11) * SHIFT24 +
1374
+ fromB64(hlc16, 12) * SHIFT18 +
1375
+ fromB64(hlc16, 13) * SHIFT12 +
1376
+ fromB64(hlc16, 14) * SHIFT6 +
1377
+ fromB64(hlc16, 15),
1378
+ ];
1379
+ const getHlcFunctions = (uniqueId) => {
1380
+ let logicalTime = 0;
1381
+ let lastCounter = -1;
1382
+ const uniqueIdHash = getHash(uniqueId);
1383
+ const getHlc = () => {
1384
+ seenHlc();
1385
+ return encodeHlc(logicalTime, ++lastCounter, uniqueIdHash);
1386
+ };
1387
+ const seenHlc = (hlc) => {
1388
+ const previousLogicalTime = logicalTime;
1389
+ const [remoteLogicalTime, remoteCounter] =
1390
+ isUndefined(hlc) || hlc == '' ? [0, 0] : decodeHlc(hlc);
1391
+ logicalTime = mathMax(
1392
+ previousLogicalTime,
1393
+ remoteLogicalTime,
1394
+ globalThis.HLC_TIME ?? Date.now(),
1395
+ );
1396
+ lastCounter =
1397
+ logicalTime == previousLogicalTime
1398
+ ? logicalTime == remoteLogicalTime
1399
+ ? mathMax(lastCounter, remoteCounter)
1400
+ : lastCounter
1401
+ : logicalTime == remoteLogicalTime
1402
+ ? remoteCounter
1403
+ : -1;
1404
+ };
1405
+ return [getHlc, seenHlc];
1406
+ };
1407
+
1408
+ const RESPONSE = 0;
1409
+ const GET_CONTENT_HASHES = 1;
1410
+ const CONTENT_HASHES = 2;
1411
+ const CONTENT_DIFF = 3;
1412
+ const GET_TABLE_DIFF = 4;
1413
+ const GET_ROW_DIFF = 5;
1414
+ const GET_CELL_DIFF = 6;
1415
+ const GET_VALUE_DIFF = 7;
1416
+ const createCustomSynchronizer = (
1417
+ store,
1418
+ send,
1419
+ onReceive,
1420
+ destroyImpl,
1421
+ requestTimeoutSeconds,
1422
+ onIgnoredError,
1423
+ extra = {},
1424
+ ) => {
1425
+ let persisterListener;
1426
+ let sends = 0;
1427
+ let receives = 0;
1428
+ const [getHlc] = getHlcFunctions(store.getId());
1429
+ const pendingRequests = mapNew();
1430
+ onReceive((fromClientId, requestId, messageType, messageBody) => {
1431
+ {
1432
+ receives++;
1433
+ }
1434
+ if (messageType == RESPONSE) {
1435
+ ifNotUndefined(
1436
+ mapGet(pendingRequests, requestId),
1437
+ ([toClientId, handleResponse]) =>
1438
+ isUndefined(toClientId) || toClientId == fromClientId
1439
+ ? handleResponse(messageBody, fromClientId)
1440
+ : /* istanbul ignore next */
1441
+ 0,
1442
+ );
1443
+ } else if (messageType == CONTENT_HASHES && persister.isAutoLoading()) {
1444
+ getChangesFromOtherStore(fromClientId, messageBody).then((changes) => {
1445
+ persisterListener?.(void 0, () => changes);
1446
+ });
1447
+ } else if (messageType == CONTENT_DIFF && persister.isAutoLoading()) {
1448
+ persisterListener?.(void 0, () => messageBody);
1449
+ } else {
1450
+ ifNotUndefined(
1451
+ messageType == GET_CONTENT_HASHES && persister.isAutoSaving()
1452
+ ? store.getMergeableContentHashes()
1453
+ : messageType == GET_TABLE_DIFF
1454
+ ? store.getMergeableTableDiff(messageBody)
1455
+ : messageType == GET_ROW_DIFF
1456
+ ? store.getMergeableRowDiff(messageBody)
1457
+ : messageType == GET_CELL_DIFF
1458
+ ? store.getMergeableCellDiff(messageBody)
1459
+ : messageType == GET_VALUE_DIFF
1460
+ ? store.getMergeableValueDiff(messageBody)
1461
+ : void 0,
1462
+ (response) => {
1463
+ {
1464
+ sends++;
1465
+ }
1466
+ send(fromClientId, requestId, RESPONSE, response);
1467
+ },
1468
+ );
1469
+ }
1470
+ });
1471
+ const request = async (toClientId, messageType, messageBody = EMPTY_STRING) =>
1472
+ promiseNew((resolve, reject) => {
1473
+ const requestId = getHlc();
1474
+ const timeout = setTimeout(() => {
1475
+ collDel(pendingRequests, requestId);
1476
+ reject(
1477
+ `No response from ${toClientId ?? 'anyone'} to '${messageType}'`,
1478
+ );
1479
+ }, requestTimeoutSeconds * 1e3);
1480
+ mapSet(pendingRequests, requestId, [
1481
+ toClientId,
1482
+ (response, fromClientId) => {
1483
+ clearTimeout(timeout);
1484
+ collDel(pendingRequests, requestId);
1485
+ resolve([response, fromClientId]);
1486
+ },
1487
+ ]);
1488
+ {
1489
+ sends++;
1490
+ }
1491
+ send(toClientId, requestId, messageType, messageBody);
1492
+ });
1493
+ const mergeTablesStamps = (tablesStamp, [tableStamps2, tablesTime2]) => {
1494
+ objForEach(tableStamps2, ([rowStamps2, tableTime2], tableId) => {
1495
+ const tableStamp = objEnsure(tablesStamp[0], tableId, stampNewObj);
1496
+ objForEach(rowStamps2, ([cellStamps2, rowTime2], rowId) => {
1497
+ const rowStamp = objEnsure(tableStamp[0], rowId, stampNewObj);
1498
+ objForEach(
1499
+ cellStamps2,
1500
+ ([cell2, cellTime2], cellId) =>
1501
+ (rowStamp[0][cellId] = newStamp(cell2, cellTime2)),
1502
+ );
1503
+ rowStamp[1] = getLatestTime(rowStamp[1], rowTime2);
1504
+ });
1505
+ tableStamp[1] = getLatestTime(tableStamp[1], tableTime2);
1506
+ });
1507
+ tablesStamp[1] = getLatestTime(tablesStamp[1], tablesTime2);
1508
+ };
1509
+ const getChangesFromOtherStore = async (
1510
+ otherClientId = null,
1511
+ otherContentHashes,
1512
+ ) => {
1513
+ if (isUndefined(otherContentHashes)) {
1514
+ [otherContentHashes, otherClientId] = await request(
1515
+ otherClientId,
1516
+ GET_CONTENT_HASHES,
1517
+ );
1518
+ }
1519
+ const [otherTablesHash, otherValuesHash] = otherContentHashes;
1520
+ const [tablesHash, valuesHash] = store.getMergeableContentHashes();
1521
+ let tablesChanges = stampNewObj();
1522
+ if (tablesHash != otherTablesHash) {
1523
+ const [newTables, differentTableHashes] = (
1524
+ await request(
1525
+ otherClientId,
1526
+ GET_TABLE_DIFF,
1527
+ store.getMergeableTableHashes(),
1528
+ )
1529
+ )[0];
1530
+ tablesChanges = newTables;
1531
+ if (!objIsEmpty(differentTableHashes)) {
1532
+ const [newRows, differentRowHashes] = (
1533
+ await request(
1534
+ otherClientId,
1535
+ GET_ROW_DIFF,
1536
+ store.getMergeableRowHashes(differentTableHashes),
1537
+ )
1538
+ )[0];
1539
+ mergeTablesStamps(tablesChanges, newRows);
1540
+ if (!objIsEmpty(differentRowHashes)) {
1541
+ const newCells = (
1542
+ await request(
1543
+ otherClientId,
1544
+ GET_CELL_DIFF,
1545
+ store.getMergeableCellHashes(differentRowHashes),
1546
+ )
1547
+ )[0];
1548
+ mergeTablesStamps(tablesChanges, newCells);
1549
+ }
1550
+ }
1551
+ }
1552
+ return [
1553
+ tablesChanges,
1554
+ valuesHash == otherValuesHash
1555
+ ? stampNewObj()
1556
+ : (
1557
+ await request(
1558
+ otherClientId,
1559
+ GET_VALUE_DIFF,
1560
+ store.getMergeableValuesHashes(),
1561
+ )
1562
+ )[0],
1563
+ 1,
1564
+ ];
1565
+ };
1566
+ const getPersisted = async () => {
1567
+ const changes = await getChangesFromOtherStore();
1568
+ return !objIsEmpty(changes[0][0]) || !objIsEmpty(changes[1][0])
1569
+ ? changes
1570
+ : void 0;
1571
+ };
1572
+ const setPersisted = async (getContent, getChanges) => {
1573
+ {
1574
+ sends++;
1575
+ }
1576
+ if (getChanges) {
1577
+ send(null, null, CONTENT_DIFF, getChanges());
1578
+ } else {
1579
+ send(null, null, CONTENT_HASHES, store.getMergeableContentHashes());
1580
+ }
1581
+ };
1582
+ const addPersisterListener = (listener) => (persisterListener = listener);
1583
+ const delPersisterListener = () => (persisterListener = void 0);
1584
+ const startSync = async (initialContent) =>
1585
+ await (await persister.startAutoLoad(initialContent)).startAutoSave();
1586
+ const stopSync = () => persister.stopAutoLoad().stopAutoSave();
1587
+ const destroy = () => {
1588
+ destroyImpl();
1589
+ return persister.stopSync();
1590
+ };
1591
+ const getSynchronizerStats = () => ({sends, receives});
1592
+ const persister = createCustomPersister(
1593
+ store,
1594
+ getPersisted,
1595
+ setPersisted,
1596
+ addPersisterListener,
1597
+ delPersisterListener,
1598
+ onIgnoredError,
1599
+ true,
1600
+ {startSync, stopSync, destroy, getSynchronizerStats, ...extra},
1601
+ );
1602
+ return persister;
1603
+ };
1604
+
1205
1605
  const createQueries = getCreateFunction((store) => {
1206
1606
  const createStore = store.createStore;
1207
1607
  const preStore = createStore();
@@ -1629,7 +2029,7 @@ const createQueries = getCreateFunction((store) => {
1629
2029
  destroy,
1630
2030
  getListenerStats,
1631
2031
  };
1632
- objMap(
2032
+ objToArray(
1633
2033
  {
1634
2034
  [TABLE]: [1, 1],
1635
2035
  [TABLE + CELL_IDS]: [0, 1],
@@ -1856,24 +2256,12 @@ const pairNewMap = () => [mapNew(), mapNew()];
1856
2256
  const pairClone = (array) => [...array];
1857
2257
  const pairIsEqual = ([entry1, entry2]) => entry1 === entry2;
1858
2258
 
1859
- const jsonString = (obj) =>
2259
+ const jsonStringWithMap = (obj) =>
1860
2260
  JSON.stringify(obj, (_key, value) =>
1861
2261
  isInstanceOf(value, Map) ? object.fromEntries([...value]) : value,
1862
2262
  );
1863
2263
  const jsonParse = JSON.parse;
1864
2264
 
1865
- const validate = (obj, validateChild, onInvalidObj) => {
1866
- if (isUndefined(obj) || !isObject(obj) || objIsEmpty(obj) || objFrozen(obj)) {
1867
- onInvalidObj?.();
1868
- return false;
1869
- }
1870
- objMap(obj, (child, id2) => {
1871
- if (!validateChild(child, id2)) {
1872
- objDel(obj, id2);
1873
- }
1874
- });
1875
- return !objIsEmpty(obj);
1876
- };
1877
2265
  const idsChanged = (changedIds, id2, addedOrRemoved) =>
1878
2266
  mapSet(
1879
2267
  changedIds,
@@ -1883,11 +2271,10 @@ const idsChanged = (changedIds, id2, addedOrRemoved) =>
1883
2271
  const createStore = () => {
1884
2272
  let hasTablesSchema;
1885
2273
  let hasValuesSchema;
1886
- let cellsTouched = false;
1887
- let valuesTouched = false;
1888
2274
  let hadTables = false;
1889
2275
  let hadValues = false;
1890
2276
  let transactions = 0;
2277
+ let internalListeners = [];
1891
2278
  const changedTableIds = mapNew();
1892
2279
  const changedTableCellIds = mapNew();
1893
2280
  const changedRowCount = mapNew();
@@ -1934,13 +2321,13 @@ const createStore = () => {
1934
2321
  const [addListener, callListeners, delListenerImpl, callListenerImpl] =
1935
2322
  getListenerFunctions(() => store);
1936
2323
  const validateTablesSchema = (tableSchema) =>
1937
- validate(tableSchema, (tableSchema2) =>
1938
- validate(tableSchema2, validateCellOrValueSchema),
2324
+ objValidate(tableSchema, (tableSchema2) =>
2325
+ objValidate(tableSchema2, validateCellOrValueSchema),
1939
2326
  );
1940
2327
  const validateValuesSchema = (valuesSchema) =>
1941
- validate(valuesSchema, validateCellOrValueSchema);
2328
+ objValidate(valuesSchema, validateCellOrValueSchema);
1942
2329
  const validateCellOrValueSchema = (schema) => {
1943
- if (!validate(schema, (_child, id2) => arrayHas([TYPE, DEFAULT], id2))) {
2330
+ if (!objValidate(schema, (_child, id2) => arrayHas([TYPE, DEFAULT], id2))) {
1944
2331
  return false;
1945
2332
  }
1946
2333
  const type = schema[TYPE];
@@ -1953,18 +2340,18 @@ const createStore = () => {
1953
2340
  return true;
1954
2341
  };
1955
2342
  const validateTables = (tables) =>
1956
- validate(tables, validateTable, cellInvalid);
2343
+ objValidate(tables, validateTable, cellInvalid);
1957
2344
  const validateTable = (table, tableId) =>
1958
2345
  (!hasTablesSchema ||
1959
2346
  collHas(tablesSchemaMap, tableId) ||
1960
2347
  cellInvalid(tableId)) &&
1961
- validate(
2348
+ objValidate(
1962
2349
  table,
1963
2350
  (row, rowId) => validateRow(tableId, rowId, row),
1964
2351
  () => cellInvalid(tableId),
1965
2352
  );
1966
2353
  const validateRow = (tableId, rowId, row, skipDefaults) =>
1967
- validate(
2354
+ objValidate(
1968
2355
  skipDefaults ? row : addDefaultsToRow(row, tableId, rowId),
1969
2356
  (cell, cellId) =>
1970
2357
  ifNotUndefined(
@@ -1991,7 +2378,7 @@ const createStore = () => {
1991
2378
  ? cellInvalid(tableId, rowId, cellId, cell)
1992
2379
  : cell;
1993
2380
  const validateValues = (values, skipDefaults) =>
1994
- validate(
2381
+ objValidate(
1995
2382
  skipDefaults ? values : addDefaultsToValues(values),
1996
2383
  (value, valueId) =>
1997
2384
  ifNotUndefined(
@@ -2254,16 +2641,20 @@ const createStore = () => {
2254
2641
  addedOrRemoved,
2255
2642
  );
2256
2643
  };
2257
- const cellChanged = (tableId, rowId, cellId, oldCell, newCell) =>
2258
- (mapEnsure(
2644
+ const cellChanged = (tableId, rowId, cellId, oldCell, newCell) => {
2645
+ mapEnsure(
2259
2646
  mapEnsure(mapEnsure(changedCells, tableId, mapNew), rowId, mapNew),
2260
2647
  cellId,
2261
2648
  () => [oldCell, 0],
2262
- )[1] = newCell);
2649
+ )[1] = newCell;
2650
+ internalListeners[3]?.(tableId, rowId, cellId, newCell);
2651
+ };
2263
2652
  const valueIdsChanged = (valueId, addedOrRemoved) =>
2264
2653
  idsChanged(changedValueIds, valueId, addedOrRemoved);
2265
- const valueChanged = (valueId, oldValue, newValue) =>
2266
- (mapEnsure(changedValues, valueId, () => [oldValue, 0])[1] = newValue);
2654
+ const valueChanged = (valueId, oldValue, newValue) => {
2655
+ mapEnsure(changedValues, valueId, () => [oldValue, 0])[1] = newValue;
2656
+ internalListeners[4]?.(valueId, newValue);
2657
+ };
2267
2658
  const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
2268
2659
  arrayPush(
2269
2660
  mapEnsure(
@@ -2529,44 +2920,6 @@ const createStore = () => {
2529
2920
  transaction(() => actions(...arrayMap(args, id)));
2530
2921
  return store;
2531
2922
  };
2532
- const getTransactionChanges = () => [
2533
- mapToObj(
2534
- changedCells,
2535
- (table, tableId) =>
2536
- mapGet(changedTableIds, tableId) === -1
2537
- ? null
2538
- : mapToObj(
2539
- table,
2540
- (row, rowId) =>
2541
- mapGet(mapGet(changedRowIds, tableId), rowId) === -1
2542
- ? null
2543
- : mapToObj(
2544
- row,
2545
- ([, newCell]) => newCell ?? null,
2546
- (_, changedCell) => pairIsEqual(changedCell),
2547
- ),
2548
- objIsEmpty,
2549
- ),
2550
- objIsEmpty,
2551
- ),
2552
- mapToObj(
2553
- changedValues,
2554
- ([, newValue]) => newValue ?? null,
2555
- (_, changedValue) => pairIsEqual(changedValue),
2556
- ),
2557
- ];
2558
- const getTransactionLog = () => ({
2559
- cellsTouched,
2560
- valuesTouched,
2561
- changedCells: mapToObj3(changedCells, pairClone, pairIsEqual),
2562
- invalidCells: mapToObj3(invalidCells),
2563
- changedValues: mapToObj(changedValues, pairClone, pairIsEqual),
2564
- invalidValues: mapToObj(invalidValues),
2565
- changedTableIds: mapToObj(changedTableIds),
2566
- changedRowIds: mapToObj2(changedRowIds),
2567
- changedCellIds: mapToObj3(changedCellIds),
2568
- changedValueIds: mapToObj(changedValueIds),
2569
- });
2570
2923
  const getContent = () => [getTables(), getValues()];
2571
2924
  const getTables = () => mapToObj3(tablesMap);
2572
2925
  const getTableIds = () => mapKeys(tablesMap);
@@ -2610,12 +2963,13 @@ const createStore = () => {
2610
2963
  collHas(mapGet(mapGet(tablesMap, id(tableId)), id(rowId)), id(cellId));
2611
2964
  const hasValues = () => !collIsEmpty(valuesMap);
2612
2965
  const hasValue = (valueId) => collHas(valuesMap, id(valueId));
2613
- const getTablesJson = () => jsonString(tablesMap);
2614
- const getValuesJson = () => jsonString(valuesMap);
2615
- const getJson = () => jsonString([tablesMap, valuesMap]);
2616
- const getTablesSchemaJson = () => jsonString(tablesSchemaMap);
2617
- const getValuesSchemaJson = () => jsonString(valuesSchemaMap);
2618
- const getSchemaJson = () => jsonString([tablesSchemaMap, valuesSchemaMap]);
2966
+ const getTablesJson = () => jsonStringWithMap(tablesMap);
2967
+ const getValuesJson = () => jsonStringWithMap(valuesMap);
2968
+ const getJson = () => jsonStringWithMap([tablesMap, valuesMap]);
2969
+ const getTablesSchemaJson = () => jsonStringWithMap(tablesSchemaMap);
2970
+ const getValuesSchemaJson = () => jsonStringWithMap(valuesSchemaMap);
2971
+ const getSchemaJson = () =>
2972
+ jsonStringWithMap([tablesSchemaMap, valuesSchemaMap]);
2619
2973
  const setContent = ([tables, values]) =>
2620
2974
  fluentTransaction(() => {
2621
2975
  (objIsEmpty(tables) ? delTables : setTables)(tables);
@@ -2659,7 +3013,7 @@ const createStore = () => {
2659
3013
  (tableId2, rowId2) => {
2660
3014
  if (validateRow(tableId2, rowId2, partialRow, 1)) {
2661
3015
  const table = getOrCreateTable(tableId2);
2662
- objMap(partialRow, (cell, cellId) =>
3016
+ objToArray(partialRow, (cell, cellId) =>
2663
3017
  setCellIntoDefaultRow(tableId2, table, rowId2, cellId, cell),
2664
3018
  );
2665
3019
  }
@@ -2697,7 +3051,7 @@ const createStore = () => {
2697
3051
  const setPartialValues = (partialValues) =>
2698
3052
  fluentTransaction(() =>
2699
3053
  validateValues(partialValues, 1)
2700
- ? objMap(partialValues, (value, valueId) =>
3054
+ ? objToArray(partialValues, (value, valueId) =>
2701
3055
  setValidValue(valueId, value),
2702
3056
  )
2703
3057
  : 0,
@@ -2714,20 +3068,20 @@ const createStore = () => {
2714
3068
  ),
2715
3069
  valueId,
2716
3070
  );
2717
- const setTransactionChanges = (transactionChanges) =>
3071
+ const applyChanges = (changes) =>
2718
3072
  fluentTransaction(() => {
2719
- objMap(transactionChanges[0], (table, tableId) =>
3073
+ objToArray(changes[0], (table, tableId) =>
2720
3074
  isUndefined(table)
2721
3075
  ? delTable(tableId)
2722
- : objMap(table, (row, rowId) =>
3076
+ : objToArray(table, (row, rowId) =>
2723
3077
  isUndefined(row)
2724
3078
  ? delRow(tableId, rowId)
2725
- : objMap(row, (cell, cellId) =>
3079
+ : objToArray(row, (cell, cellId) =>
2726
3080
  setOrDelCell(store, tableId, rowId, cellId, cell),
2727
3081
  ),
2728
3082
  ),
2729
3083
  );
2730
- objMap(transactionChanges[1], (value, valueId) =>
3084
+ objToArray(changes[1], (value, valueId) =>
2731
3085
  setOrDelValue(store, valueId, value),
2732
3086
  );
2733
3087
  });
@@ -2854,31 +3208,66 @@ const createStore = () => {
2854
3208
  transactions++;
2855
3209
  }
2856
3210
  if (transactions == 1) {
2857
- callListeners(
2858
- startTransactionListeners,
2859
- void 0,
2860
- getTransactionChanges,
2861
- getTransactionLog,
2862
- );
3211
+ internalListeners[0]?.();
3212
+ callListeners(startTransactionListeners, void 0);
2863
3213
  }
2864
3214
  return store;
2865
3215
  };
3216
+ const getTransactionChanges = () => [
3217
+ mapToObj(
3218
+ changedCells,
3219
+ (table, tableId) =>
3220
+ mapGet(changedTableIds, tableId) === -1
3221
+ ? void 0
3222
+ : mapToObj(
3223
+ table,
3224
+ (row, rowId) =>
3225
+ mapGet(mapGet(changedRowIds, tableId), rowId) === -1
3226
+ ? void 0
3227
+ : mapToObj(
3228
+ row,
3229
+ ([, newCell]) => newCell,
3230
+ (changedCell) => pairIsEqual(changedCell),
3231
+ ),
3232
+ collIsEmpty,
3233
+ objIsEmpty,
3234
+ ),
3235
+ collIsEmpty,
3236
+ objIsEmpty,
3237
+ ),
3238
+ mapToObj(
3239
+ changedValues,
3240
+ ([, newValue]) => newValue,
3241
+ (changedValue) => pairIsEqual(changedValue),
3242
+ ),
3243
+ 1,
3244
+ ];
3245
+ const getTransactionLog = () => [
3246
+ !collIsEmpty(changedCells),
3247
+ !collIsEmpty(changedValues),
3248
+ mapToObj3(changedCells, pairClone, pairIsEqual),
3249
+ mapToObj3(invalidCells),
3250
+ mapToObj(changedValues, pairClone, pairIsEqual),
3251
+ mapToObj(invalidValues),
3252
+ mapToObj(changedTableIds),
3253
+ mapToObj2(changedRowIds),
3254
+ mapToObj3(changedCellIds),
3255
+ mapToObj(changedValueIds),
3256
+ ];
2866
3257
  const finishTransaction = (doRollback) => {
2867
3258
  if (transactions > 0) {
2868
3259
  transactions--;
2869
3260
  if (transactions == 0) {
2870
- cellsTouched = !collIsEmpty(changedCells);
2871
- valuesTouched = !collIsEmpty(changedValues);
2872
3261
  transactions = 1;
2873
3262
  callInvalidCellListeners(1);
2874
- if (cellsTouched) {
3263
+ if (!collIsEmpty(changedCells)) {
2875
3264
  callTabularListenersForChanges(1);
2876
3265
  }
2877
3266
  callInvalidValueListeners(1);
2878
- if (valuesTouched) {
3267
+ if (!collIsEmpty(changedValues)) {
2879
3268
  callValuesListenersForChanges(1);
2880
3269
  }
2881
- if (doRollback?.(getTransactionChanges, getTransactionLog)) {
3270
+ if (doRollback?.(store)) {
2882
3271
  collForEach(changedCells, (table, tableId) =>
2883
3272
  collForEach(table, (row, rowId) =>
2884
3273
  collForEach(row, ([oldCell], cellId) =>
@@ -2886,34 +3275,26 @@ const createStore = () => {
2886
3275
  ),
2887
3276
  ),
2888
3277
  );
3278
+ collClear(changedCells);
2889
3279
  collForEach(changedValues, ([oldValue], valueId) =>
2890
3280
  setOrDelValue(store, valueId, oldValue),
2891
3281
  );
2892
- cellsTouched = valuesTouched = false;
3282
+ collClear(changedValues);
2893
3283
  }
2894
- callListeners(
2895
- finishTransactionListeners[0],
2896
- void 0,
2897
- getTransactionChanges,
2898
- getTransactionLog,
2899
- );
3284
+ callListeners(finishTransactionListeners[0], void 0);
2900
3285
  transactions = -1;
2901
3286
  callInvalidCellListeners(0);
2902
- if (cellsTouched) {
3287
+ if (!collIsEmpty(changedCells)) {
2903
3288
  callTabularListenersForChanges(0);
2904
3289
  }
2905
3290
  callInvalidValueListeners(0);
2906
- if (valuesTouched) {
3291
+ if (!collIsEmpty(changedValues)) {
2907
3292
  callValuesListenersForChanges(0);
2908
3293
  }
2909
- callListeners(
2910
- finishTransactionListeners[1],
2911
- void 0,
2912
- getTransactionChanges,
2913
- getTransactionLog,
2914
- );
3294
+ internalListeners[1]?.();
3295
+ callListeners(finishTransactionListeners[1], void 0);
3296
+ internalListeners[2]?.();
2915
3297
  transactions = 0;
2916
- cellsTouched = valuesTouched = false;
2917
3298
  hadTables = hasTables();
2918
3299
  hadValues = hasValues();
2919
3300
  arrayForEach(
@@ -3038,6 +3419,20 @@ const createStore = () => {
3038
3419
  collSize2(startTransactionListeners) +
3039
3420
  pairCollSize2(finishTransactionListeners),
3040
3421
  });
3422
+ const setInternalListeners = (
3423
+ preStartTransaction,
3424
+ preFinishTransaction,
3425
+ postFinishTransaction,
3426
+ cellChanged2,
3427
+ valueChanged2,
3428
+ ) =>
3429
+ (internalListeners = [
3430
+ preStartTransaction,
3431
+ preFinishTransaction,
3432
+ postFinishTransaction,
3433
+ cellChanged2,
3434
+ valueChanged2,
3435
+ ]);
3041
3436
  const store = {
3042
3437
  getContent,
3043
3438
  getTables,
@@ -3078,7 +3473,7 @@ const createStore = () => {
3078
3473
  setValues,
3079
3474
  setPartialValues,
3080
3475
  setValue,
3081
- setTransactionChanges,
3476
+ applyChanges,
3082
3477
  setTablesJson,
3083
3478
  setValuesJson,
3084
3479
  setJson,
@@ -3096,6 +3491,8 @@ const createStore = () => {
3096
3491
  delSchema,
3097
3492
  transaction,
3098
3493
  startTransaction,
3494
+ getTransactionChanges,
3495
+ getTransactionLog,
3099
3496
  finishTransaction,
3100
3497
  forEachTable,
3101
3498
  forEachTableCell,
@@ -3113,8 +3510,9 @@ const createStore = () => {
3113
3510
  createStore,
3114
3511
  addListener,
3115
3512
  callListeners,
3513
+ setInternalListeners,
3116
3514
  };
3117
- objMap(
3515
+ objToArray(
3118
3516
  {
3119
3517
  [HAS + TABLES]: [0, hasTablesListeners, [], () => [hasTables()]],
3120
3518
  [TABLES]: [0, tablesListeners],
@@ -3187,10 +3585,484 @@ const createStore = () => {
3187
3585
  return objFreeze(store);
3188
3586
  };
3189
3587
 
3588
+ const LISTENER_ARGS = {
3589
+ HasTable: 1,
3590
+ Table: 1,
3591
+ TableCellIds: 1,
3592
+ HasTableCell: 2,
3593
+ RowCount: 1,
3594
+ RowIds: 1,
3595
+ SortedRowIds: 5,
3596
+ HasRow: 2,
3597
+ Row: 2,
3598
+ CellIds: 2,
3599
+ HasCell: 3,
3600
+ Cell: 3,
3601
+ HasValue: 1,
3602
+ Value: 1,
3603
+ InvalidCell: 3,
3604
+ InvalidValue: 1,
3605
+ };
3606
+ const newContentStampMap = (time = EMPTY_STRING) => [
3607
+ stampNewMap(time),
3608
+ stampNewMap(time),
3609
+ ];
3610
+ const validateMergeableContent = (mergeableContent) =>
3611
+ isArray(mergeableContent) &&
3612
+ size(mergeableContent) == 2 &&
3613
+ stampValidate(mergeableContent[0], (tableStamps) =>
3614
+ objValidate(
3615
+ tableStamps,
3616
+ (tableStamp) =>
3617
+ stampValidate(tableStamp, (rowStamps) =>
3618
+ objValidate(
3619
+ rowStamps,
3620
+ (rowStamp) =>
3621
+ stampValidate(rowStamp, (cellStamps) =>
3622
+ objValidate(
3623
+ cellStamps,
3624
+ (cellStamp) =>
3625
+ stampValidate(cellStamp, isCellOrValueOrNullOrUndefined),
3626
+ void 0,
3627
+ 1,
3628
+ ),
3629
+ ),
3630
+ void 0,
3631
+ 1,
3632
+ ),
3633
+ ),
3634
+ void 0,
3635
+ 1,
3636
+ ),
3637
+ ) &&
3638
+ stampValidate(mergeableContent[1], (values) =>
3639
+ objValidate(
3640
+ values,
3641
+ (value) => stampValidate(value, isCellOrValueOrNullOrUndefined),
3642
+ void 0,
3643
+ 1,
3644
+ ),
3645
+ );
3646
+ const createMergeableStore = (id) => {
3647
+ let listeningToRawStoreChanges = 1;
3648
+ let contentStampMap = newContentStampMap();
3649
+ let defaultingContent = 0;
3650
+ const touchedCells = mapNew();
3651
+ const touchedValues = setNew();
3652
+ const [getHlc, seenHlc] = getHlcFunctions(id);
3653
+ const store = createStore();
3654
+ const disableListeningToRawStoreChanges = (actions) => {
3655
+ const wasListening = listeningToRawStoreChanges;
3656
+ listeningToRawStoreChanges = 0;
3657
+ actions();
3658
+ listeningToRawStoreChanges = wasListening;
3659
+ return mergeableStore;
3660
+ };
3661
+ const mergeContentOrChanges = (contentOrChanges, isContent = 0) => {
3662
+ const tablesChanges = {};
3663
+ const valuesChanges = {};
3664
+ const [
3665
+ [tablesObj, incomingTablesTime = EMPTY_STRING, incomingTablesHash = 0],
3666
+ values,
3667
+ ] = contentOrChanges;
3668
+ const [tablesStampMap, valuesStampMap] = contentStampMap;
3669
+ const [tableStampMaps, oldTablesTime, oldTablesHash] = tablesStampMap;
3670
+ let tablesHash = isContent ? incomingTablesHash : oldTablesHash;
3671
+ let tablesTime = incomingTablesTime;
3672
+ objForEach(
3673
+ tablesObj,
3674
+ (
3675
+ [rowsObj, incomingTableTime = EMPTY_STRING, incomingTableHash = 0],
3676
+ tableId,
3677
+ ) => {
3678
+ const tableStampMap = mapEnsure(tableStampMaps, tableId, stampNewMap);
3679
+ const [rowStampMaps, oldTableTime, oldTableHash] = tableStampMap;
3680
+ let tableHash = isContent ? incomingTableHash : oldTableHash;
3681
+ let tableTime = incomingTableTime;
3682
+ objForEach(rowsObj, (row, rowId) => {
3683
+ const [rowTime, oldRowHash, rowHash] = mergeCellsOrValues(
3684
+ row,
3685
+ mapEnsure(rowStampMaps, rowId, stampNewMap),
3686
+ objEnsure(objEnsure(tablesChanges, tableId, objNew), rowId, objNew),
3687
+ isContent,
3688
+ );
3689
+ tableHash ^= isContent
3690
+ ? 0
3691
+ : (oldRowHash ? hashIdAndHash(rowId, oldRowHash) : 0) ^
3692
+ hashIdAndHash(rowId, rowHash);
3693
+ tableTime = getLatestTime(tableTime, rowTime);
3694
+ });
3695
+ tableHash ^= isContent
3696
+ ? 0
3697
+ : replaceTimeHash(oldTableTime, incomingTableTime);
3698
+ stampUpdate(tableStampMap, tableHash, incomingTableTime);
3699
+ tablesHash ^= isContent
3700
+ ? 0
3701
+ : (oldTableHash ? hashIdAndHash(tableId, oldTableHash) : 0) ^
3702
+ hashIdAndHash(tableId, tableStampMap[2]);
3703
+ tablesTime = getLatestTime(tablesTime, tableTime);
3704
+ },
3705
+ );
3706
+ tablesHash ^= isContent
3707
+ ? 0
3708
+ : replaceTimeHash(oldTablesTime, incomingTablesTime);
3709
+ stampUpdate(tablesStampMap, tablesHash, incomingTablesTime);
3710
+ const [valuesTime] = mergeCellsOrValues(
3711
+ values,
3712
+ valuesStampMap,
3713
+ valuesChanges,
3714
+ isContent,
3715
+ );
3716
+ seenHlc(getLatestTime(tablesTime, valuesTime));
3717
+ return [tablesChanges, valuesChanges, 1];
3718
+ };
3719
+ const mergeCellsOrValues = (
3720
+ things,
3721
+ thingsStampMap,
3722
+ thingsChanges,
3723
+ isContent,
3724
+ ) => {
3725
+ const [
3726
+ thingsObj,
3727
+ incomingThingsTime = EMPTY_STRING,
3728
+ incomingThingsHash = 0,
3729
+ ] = things;
3730
+ const [thingStampMaps, oldThingsTime, oldThingsHash] = thingsStampMap;
3731
+ let thingsTime = incomingThingsTime;
3732
+ let thingsHash = isContent ? incomingThingsHash : oldThingsHash;
3733
+ objForEach(
3734
+ thingsObj,
3735
+ ([thing, thingTime, incomingThingHash = 0], thingId) => {
3736
+ const thingStampMap = mapEnsure(thingStampMaps, thingId, () => [
3737
+ void 0,
3738
+ EMPTY_STRING,
3739
+ 0,
3740
+ ]);
3741
+ const [, oldThingTime, oldThingHash] = thingStampMap;
3742
+ if (!oldThingTime || thingTime > oldThingTime) {
3743
+ stampUpdate(
3744
+ thingStampMap,
3745
+ isContent
3746
+ ? incomingThingHash
3747
+ : getHash(jsonStringWithMap(thing ?? null) + ':' + thingTime),
3748
+ thingTime,
3749
+ );
3750
+ thingStampMap[0] = thing;
3751
+ thingsChanges[thingId] = thing;
3752
+ thingsHash ^= isContent
3753
+ ? 0
3754
+ : hashIdAndHash(thingId, oldThingHash) ^
3755
+ hashIdAndHash(thingId, thingStampMap[2]);
3756
+ thingsTime = getLatestTime(thingsTime, thingTime);
3757
+ }
3758
+ },
3759
+ );
3760
+ thingsHash ^= isContent
3761
+ ? 0
3762
+ : replaceTimeHash(oldThingsTime, incomingThingsTime);
3763
+ stampUpdate(thingsStampMap, thingsHash, incomingThingsTime);
3764
+ return [thingsTime, oldThingsHash, thingsStampMap[2]];
3765
+ };
3766
+ const preStartTransaction = () => {};
3767
+ const preFinishTransaction = () => {};
3768
+ const postFinishTransaction = () => {
3769
+ collClear(touchedCells);
3770
+ collClear(touchedValues);
3771
+ };
3772
+ const cellChanged = (tableId, rowId, cellId, newCell) => {
3773
+ setAdd(
3774
+ mapEnsure(mapEnsure(touchedCells, tableId, mapNew), rowId, setNew),
3775
+ cellId,
3776
+ );
3777
+ if (listeningToRawStoreChanges) {
3778
+ mergeContentOrChanges([
3779
+ [
3780
+ {
3781
+ [tableId]: [
3782
+ {
3783
+ [rowId]: [
3784
+ {
3785
+ [cellId]: [
3786
+ newCell,
3787
+ defaultingContent ? EMPTY_STRING : getHlc(),
3788
+ ],
3789
+ },
3790
+ ],
3791
+ },
3792
+ ],
3793
+ },
3794
+ ],
3795
+ [{}],
3796
+ 1,
3797
+ ]);
3798
+ }
3799
+ };
3800
+ const valueChanged = (valueId, newValue) => {
3801
+ setAdd(touchedValues, valueId);
3802
+ if (listeningToRawStoreChanges) {
3803
+ mergeContentOrChanges([
3804
+ [{}],
3805
+ [{[valueId]: [newValue, defaultingContent ? EMPTY_STRING : getHlc()]}],
3806
+ 1,
3807
+ ]);
3808
+ }
3809
+ };
3810
+ const getId = () => id;
3811
+ const getMergeableContent = () => [
3812
+ stampMapToObjWithHash(contentStampMap[0], (tableStampMap) =>
3813
+ stampMapToObjWithHash(tableStampMap, (rowStampMap) =>
3814
+ stampMapToObjWithHash(rowStampMap),
3815
+ ),
3816
+ ),
3817
+ stampMapToObjWithHash(contentStampMap[1]),
3818
+ ];
3819
+ const getMergeableContentHashes = () => [
3820
+ contentStampMap[0][2],
3821
+ contentStampMap[1][2],
3822
+ ];
3823
+ const getMergeableTableHashes = () =>
3824
+ mapToObj(contentStampMap[0][0], getStampHash);
3825
+ const getMergeableTableDiff = (otherTableHashes) => {
3826
+ const newTables = stampNewObj(contentStampMap[0][1]);
3827
+ const differentTableHashes = {};
3828
+ mapForEach(
3829
+ contentStampMap[0][0],
3830
+ (tableId, [tableStampMap, tableTime, hash]) =>
3831
+ objHas(otherTableHashes, tableId)
3832
+ ? hash != otherTableHashes[tableId]
3833
+ ? (differentTableHashes[tableId] = hash)
3834
+ : 0
3835
+ : (newTables[0][tableId] = stampMapToObjWithoutHash(
3836
+ [tableStampMap, tableTime],
3837
+ (rowStampMap) => stampMapToObjWithoutHash(rowStampMap),
3838
+ )),
3839
+ );
3840
+ return [newTables, differentTableHashes];
3841
+ };
3842
+ const getMergeableRowHashes = (otherTableHashes) => {
3843
+ const rowHashes = {};
3844
+ objForEach(otherTableHashes, (otherTableHash, tableId) =>
3845
+ ifNotUndefined(
3846
+ mapGet(contentStampMap[0][0], tableId),
3847
+ ([rowStampMaps, , tableHash]) =>
3848
+ tableHash != otherTableHash
3849
+ ? mapForEach(
3850
+ rowStampMaps,
3851
+ (rowId, [, , rowHash]) =>
3852
+ (objEnsure(rowHashes, tableId, objNew)[rowId] = rowHash),
3853
+ )
3854
+ : 0,
3855
+ ),
3856
+ );
3857
+ return rowHashes;
3858
+ };
3859
+ const getMergeableRowDiff = (otherTableRowHashes) => {
3860
+ const newRows = stampNewObj(contentStampMap[0][1]);
3861
+ const differentRowHashes = {};
3862
+ objForEach(otherTableRowHashes, (otherRowHashes, tableId) =>
3863
+ mapForEach(
3864
+ mapGet(contentStampMap[0][0], tableId)?.[0],
3865
+ (rowId, [rowStampMap, rowTime, hash]) =>
3866
+ objHas(otherRowHashes, rowId)
3867
+ ? hash !== otherRowHashes[rowId]
3868
+ ? (objEnsure(differentRowHashes, tableId, objNew)[rowId] = hash)
3869
+ : 0
3870
+ : (objEnsure(newRows[0], tableId, stampNewObj)[0][rowId] =
3871
+ stampMapToObjWithoutHash([rowStampMap, rowTime])),
3872
+ ),
3873
+ );
3874
+ return [newRows, differentRowHashes];
3875
+ };
3876
+ const getMergeableCellHashes = (otherTableRowHashes) => {
3877
+ const cellHashes = {};
3878
+ objForEach(otherTableRowHashes, (otherRowHashes, tableId) =>
3879
+ ifNotUndefined(mapGet(contentStampMap[0][0], tableId), ([rowStampMaps]) =>
3880
+ objForEach(otherRowHashes, (otherRowHash, rowId) =>
3881
+ ifNotUndefined(
3882
+ mapGet(rowStampMaps, rowId),
3883
+ ([cellStampMaps, , rowHash]) =>
3884
+ rowHash !== otherRowHash
3885
+ ? mapForEach(
3886
+ cellStampMaps,
3887
+ (cellId, [, , cellHash]) =>
3888
+ (objEnsure(
3889
+ objEnsure(cellHashes, tableId, objNew),
3890
+ rowId,
3891
+ objNew,
3892
+ )[cellId] = cellHash),
3893
+ )
3894
+ : 0,
3895
+ ),
3896
+ ),
3897
+ ),
3898
+ );
3899
+ return cellHashes;
3900
+ };
3901
+ const getMergeableCellDiff = (otherTableRowCellHashes) => {
3902
+ const [[tableStampMaps, tablesTime]] = contentStampMap;
3903
+ const tablesObj = {};
3904
+ objForEach(otherTableRowCellHashes, (otherRowCellHashes, tableId) =>
3905
+ objForEach(otherRowCellHashes, (otherCellHashes, rowId) =>
3906
+ ifNotUndefined(
3907
+ mapGet(tableStampMaps, tableId),
3908
+ ([rowStampMaps, tableTime]) =>
3909
+ ifNotUndefined(
3910
+ mapGet(rowStampMaps, rowId),
3911
+ ([cellStampMaps, rowTime]) =>
3912
+ mapForEach(cellStampMaps, (cellId, [cell, cellTime, hash]) =>
3913
+ hash !== otherCellHashes[cellId]
3914
+ ? (objEnsure(
3915
+ objEnsure(tablesObj, tableId, () =>
3916
+ stampNewObj(tableTime),
3917
+ )[0],
3918
+ rowId,
3919
+ () => stampNewObj(rowTime),
3920
+ )[0][cellId] = [cell, cellTime])
3921
+ : 0,
3922
+ ),
3923
+ ),
3924
+ ),
3925
+ ),
3926
+ );
3927
+ return newStamp(tablesObj, tablesTime);
3928
+ };
3929
+ const getMergeableValuesHashes = () =>
3930
+ mapToObj(contentStampMap[1][0], getStampHash);
3931
+ const getMergeableValueDiff = (relativeTo) => {
3932
+ const [, [valueStampMaps, valuesTime]] = contentStampMap;
3933
+ const values = mapToObj(
3934
+ valueStampMaps,
3935
+ stampCloneWithoutHash,
3936
+ ([, , hash], valueId) => hash == relativeTo?.[valueId],
3937
+ );
3938
+ return newStamp(values, valuesTime);
3939
+ };
3940
+ const setMergeableContent = (mergeableContent) =>
3941
+ disableListeningToRawStoreChanges(() =>
3942
+ validateMergeableContent(mergeableContent)
3943
+ ? store.transaction(() => {
3944
+ store.delTables().delValues();
3945
+ contentStampMap = newContentStampMap();
3946
+ store.applyChanges(mergeContentOrChanges(mergeableContent, 1));
3947
+ })
3948
+ : 0,
3949
+ );
3950
+ const setDefaultContent = (content) => {
3951
+ store.transaction(() => {
3952
+ defaultingContent = 1;
3953
+ store.setContent(content);
3954
+ defaultingContent = 0;
3955
+ });
3956
+ return mergeableStore;
3957
+ };
3958
+ const getTransactionMergeableChanges = () => {
3959
+ const [[tableStampMaps, tablesTime], [valueStampMaps, valuesTime]] =
3960
+ contentStampMap;
3961
+ const tablesObj = {};
3962
+ collForEach(touchedCells, (touchedTable, tableId) =>
3963
+ ifNotUndefined(
3964
+ mapGet(tableStampMaps, tableId),
3965
+ ([rowStampMaps, tableTime]) => {
3966
+ const tableObj = {};
3967
+ collForEach(touchedTable, (touchedRow, rowId) =>
3968
+ ifNotUndefined(
3969
+ mapGet(rowStampMaps, rowId),
3970
+ ([cellStampMaps, rowTime]) => {
3971
+ const rowObj = {};
3972
+ collForEach(touchedRow, (cellId) => {
3973
+ ifNotUndefined(
3974
+ mapGet(cellStampMaps, cellId),
3975
+ ([cell, time]) => (rowObj[cellId] = newStamp(cell, time)),
3976
+ );
3977
+ });
3978
+ tableObj[rowId] = newStamp(rowObj, rowTime);
3979
+ },
3980
+ ),
3981
+ );
3982
+ tablesObj[tableId] = newStamp(tableObj, tableTime);
3983
+ },
3984
+ ),
3985
+ );
3986
+ const valuesObj = {};
3987
+ collForEach(touchedValues, (valueId) =>
3988
+ ifNotUndefined(
3989
+ mapGet(valueStampMaps, valueId),
3990
+ ([value, time]) => (valuesObj[valueId] = newStamp(value, time)),
3991
+ ),
3992
+ );
3993
+ return [
3994
+ newStamp(tablesObj, tablesTime),
3995
+ newStamp(valuesObj, valuesTime),
3996
+ 1,
3997
+ ];
3998
+ };
3999
+ const applyMergeableChanges = (mergeableChanges) =>
4000
+ disableListeningToRawStoreChanges(() =>
4001
+ store.applyChanges(mergeContentOrChanges(mergeableChanges)),
4002
+ );
4003
+ const merge = (mergeableStore2) => {
4004
+ const mergeableChanges = getMergeableContent();
4005
+ const mergeableChanges2 = mergeableStore2.getMergeableContent();
4006
+ mergeableStore2.applyMergeableChanges(mergeableChanges);
4007
+ return applyMergeableChanges(mergeableChanges2);
4008
+ };
4009
+ const mergeableStore = {
4010
+ getId,
4011
+ getMergeableContent,
4012
+ getMergeableContentHashes,
4013
+ getMergeableTableHashes,
4014
+ getMergeableTableDiff,
4015
+ getMergeableRowHashes,
4016
+ getMergeableRowDiff,
4017
+ getMergeableCellHashes,
4018
+ getMergeableCellDiff,
4019
+ getMergeableValuesHashes,
4020
+ getMergeableValueDiff,
4021
+ setMergeableContent,
4022
+ setDefaultContent,
4023
+ getTransactionMergeableChanges,
4024
+ applyMergeableChanges,
4025
+ merge,
4026
+ };
4027
+ store.setInternalListeners(
4028
+ preStartTransaction,
4029
+ preFinishTransaction,
4030
+ postFinishTransaction,
4031
+ cellChanged,
4032
+ valueChanged,
4033
+ );
4034
+ objToArray(
4035
+ store,
4036
+ (method, name) =>
4037
+ (mergeableStore[name] = // fluent methods
4038
+ strStartsWith(name, 'set') ||
4039
+ strStartsWith(name, 'del') ||
4040
+ strStartsWith(name, 'apply') ||
4041
+ strEndsWith(name, 'Transaction') ||
4042
+ name == 'callListener'
4043
+ ? (...args) => {
4044
+ method(...args);
4045
+ return mergeableStore;
4046
+ }
4047
+ : strStartsWith(name, 'add') && strEndsWith(name, 'Listener')
4048
+ ? (...args) => {
4049
+ const listenerArg = LISTENER_ARGS[slice(name, 3, -8)] ?? 0;
4050
+ const listener = args[listenerArg];
4051
+ args[listenerArg] = (_store, ...args2) =>
4052
+ listener(mergeableStore, ...args2);
4053
+ return method(...args);
4054
+ }
4055
+ : method),
4056
+ );
4057
+ return objFreeze(mergeableStore);
4058
+ };
4059
+
3190
4060
  export {
3191
4061
  createCheckpoints,
3192
4062
  createCustomPersister,
4063
+ createCustomSynchronizer,
3193
4064
  createIndexes,
4065
+ createMergeableStore,
3194
4066
  createMetrics,
3195
4067
  createQueries,
3196
4068
  createRelationships,