tinybase 5.0.0-beta.1 → 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 (491) hide show
  1. package/lib/checkpoints.js +1 -1
  2. package/lib/checkpoints.js.gz +0 -0
  3. package/lib/cjs/checkpoints.cjs +1 -1
  4. package/lib/cjs/checkpoints.cjs.gz +0 -0
  5. package/lib/cjs/indexes.cjs +1 -1
  6. package/lib/cjs/indexes.cjs.gz +0 -0
  7. package/lib/cjs/mergeable-store.cjs +1 -0
  8. package/lib/cjs/mergeable-store.cjs.gz +0 -0
  9. package/lib/cjs/metrics.cjs +1 -1
  10. package/lib/cjs/metrics.cjs.gz +0 -0
  11. package/lib/cjs/persisters/persister-automerge.cjs +1 -1
  12. package/lib/cjs/persisters/persister-automerge.cjs.gz +0 -0
  13. package/lib/cjs/persisters/persister-browser.cjs +1 -1
  14. package/lib/cjs/persisters/persister-browser.cjs.gz +0 -0
  15. package/lib/cjs/persisters/persister-cr-sqlite-wasm.cjs +1 -1
  16. package/lib/cjs/persisters/persister-cr-sqlite-wasm.cjs.gz +0 -0
  17. package/lib/cjs/persisters/persister-electric-sql.cjs +1 -1
  18. package/lib/cjs/persisters/persister-electric-sql.cjs.gz +0 -0
  19. package/lib/cjs/persisters/persister-expo-sqlite-next.cjs +1 -1
  20. package/lib/cjs/persisters/persister-expo-sqlite-next.cjs.gz +0 -0
  21. package/lib/cjs/persisters/persister-expo-sqlite.cjs +1 -1
  22. package/lib/cjs/persisters/persister-expo-sqlite.cjs.gz +0 -0
  23. package/lib/cjs/persisters/persister-file.cjs +1 -1
  24. package/lib/cjs/persisters/persister-file.cjs.gz +0 -0
  25. package/lib/cjs/persisters/persister-indexed-db.cjs +1 -1
  26. package/lib/cjs/persisters/persister-indexed-db.cjs.gz +0 -0
  27. package/lib/cjs/persisters/persister-libsql.cjs +1 -0
  28. package/lib/cjs/persisters/persister-libsql.cjs.gz +0 -0
  29. package/lib/cjs/persisters/persister-partykit-client.cjs +1 -1
  30. package/lib/cjs/persisters/persister-partykit-client.cjs.gz +0 -0
  31. package/lib/cjs/persisters/persister-partykit-server.cjs +1 -1
  32. package/lib/cjs/persisters/persister-partykit-server.cjs.gz +0 -0
  33. package/lib/cjs/persisters/persister-powersync.cjs +1 -0
  34. package/lib/cjs/persisters/persister-powersync.cjs.gz +0 -0
  35. package/lib/cjs/persisters/persister-remote.cjs +1 -1
  36. package/lib/cjs/persisters/persister-remote.cjs.gz +0 -0
  37. package/lib/cjs/persisters/persister-sqlite-wasm.cjs +1 -1
  38. package/lib/cjs/persisters/persister-sqlite-wasm.cjs.gz +0 -0
  39. package/lib/cjs/persisters/persister-sqlite3.cjs +1 -1
  40. package/lib/cjs/persisters/persister-sqlite3.cjs.gz +0 -0
  41. package/lib/cjs/persisters/persister-yjs.cjs +1 -1
  42. package/lib/cjs/persisters/persister-yjs.cjs.gz +0 -0
  43. package/lib/cjs/persisters.cjs +1 -1
  44. package/lib/cjs/persisters.cjs.gz +0 -0
  45. package/lib/cjs/queries.cjs +1 -1
  46. package/lib/cjs/queries.cjs.gz +0 -0
  47. package/lib/cjs/relationships.cjs +1 -1
  48. package/lib/cjs/relationships.cjs.gz +0 -0
  49. package/lib/cjs/store.cjs +1 -1
  50. package/lib/cjs/store.cjs.gz +0 -0
  51. package/lib/cjs/synchronizers/synchronizer-local.cjs +1 -0
  52. package/lib/cjs/synchronizers/synchronizer-local.cjs.gz +0 -0
  53. package/lib/cjs/synchronizers/synchronizer-ws-client.cjs +1 -0
  54. package/lib/cjs/synchronizers/synchronizer-ws-client.cjs.gz +0 -0
  55. package/lib/cjs/synchronizers/synchronizer-ws-server.cjs +1 -0
  56. package/lib/cjs/synchronizers/synchronizer-ws-server.cjs.gz +0 -0
  57. package/lib/cjs/synchronizers.cjs +1 -0
  58. package/lib/cjs/synchronizers.cjs.gz +0 -0
  59. package/lib/cjs/tinybase.cjs +1 -1
  60. package/lib/cjs/tinybase.cjs.gz +0 -0
  61. package/lib/cjs/tools.cjs +1 -1
  62. package/lib/cjs/tools.cjs.gz +0 -0
  63. package/lib/cjs/ui-react-dom-debug.cjs +1 -1
  64. package/lib/cjs/ui-react-dom-debug.cjs.gz +0 -0
  65. package/lib/cjs/ui-react-dom.cjs +1 -1
  66. package/lib/cjs/ui-react-dom.cjs.gz +0 -0
  67. package/lib/cjs/ui-react.cjs +1 -1
  68. package/lib/cjs/ui-react.cjs.gz +0 -0
  69. package/lib/cjs-es6/checkpoints.cjs +1 -1
  70. package/lib/cjs-es6/checkpoints.cjs.gz +0 -0
  71. package/lib/cjs-es6/indexes.cjs +1 -1
  72. package/lib/cjs-es6/indexes.cjs.gz +0 -0
  73. package/lib/cjs-es6/mergeable-store.cjs +1 -0
  74. package/lib/cjs-es6/mergeable-store.cjs.gz +0 -0
  75. package/lib/cjs-es6/metrics.cjs +1 -1
  76. package/lib/cjs-es6/metrics.cjs.gz +0 -0
  77. package/lib/cjs-es6/persisters/persister-automerge.cjs +1 -1
  78. package/lib/cjs-es6/persisters/persister-automerge.cjs.gz +0 -0
  79. package/lib/cjs-es6/persisters/persister-browser.cjs +1 -1
  80. package/lib/cjs-es6/persisters/persister-browser.cjs.gz +0 -0
  81. package/lib/cjs-es6/persisters/persister-cr-sqlite-wasm.cjs +1 -1
  82. package/lib/cjs-es6/persisters/persister-cr-sqlite-wasm.cjs.gz +0 -0
  83. package/lib/cjs-es6/persisters/persister-electric-sql.cjs +1 -1
  84. package/lib/cjs-es6/persisters/persister-electric-sql.cjs.gz +0 -0
  85. package/lib/cjs-es6/persisters/persister-expo-sqlite-next.cjs +1 -1
  86. package/lib/cjs-es6/persisters/persister-expo-sqlite-next.cjs.gz +0 -0
  87. package/lib/cjs-es6/persisters/persister-expo-sqlite.cjs +1 -1
  88. package/lib/cjs-es6/persisters/persister-expo-sqlite.cjs.gz +0 -0
  89. package/lib/cjs-es6/persisters/persister-file.cjs +1 -1
  90. package/lib/cjs-es6/persisters/persister-file.cjs.gz +0 -0
  91. package/lib/cjs-es6/persisters/persister-indexed-db.cjs +1 -1
  92. package/lib/cjs-es6/persisters/persister-indexed-db.cjs.gz +0 -0
  93. package/lib/cjs-es6/persisters/persister-libsql.cjs +1 -0
  94. package/lib/cjs-es6/persisters/persister-libsql.cjs.gz +0 -0
  95. package/lib/cjs-es6/persisters/persister-partykit-client.cjs +1 -1
  96. package/lib/cjs-es6/persisters/persister-partykit-client.cjs.gz +0 -0
  97. package/lib/cjs-es6/persisters/persister-partykit-server.cjs +1 -1
  98. package/lib/cjs-es6/persisters/persister-partykit-server.cjs.gz +0 -0
  99. package/lib/cjs-es6/persisters/persister-powersync.cjs +1 -0
  100. package/lib/cjs-es6/persisters/persister-powersync.cjs.gz +0 -0
  101. package/lib/cjs-es6/persisters/persister-remote.cjs +1 -1
  102. package/lib/cjs-es6/persisters/persister-remote.cjs.gz +0 -0
  103. package/lib/cjs-es6/persisters/persister-sqlite-wasm.cjs +1 -1
  104. package/lib/cjs-es6/persisters/persister-sqlite-wasm.cjs.gz +0 -0
  105. package/lib/cjs-es6/persisters/persister-sqlite3.cjs +1 -1
  106. package/lib/cjs-es6/persisters/persister-sqlite3.cjs.gz +0 -0
  107. package/lib/cjs-es6/persisters/persister-yjs.cjs +1 -1
  108. package/lib/cjs-es6/persisters/persister-yjs.cjs.gz +0 -0
  109. package/lib/cjs-es6/persisters.cjs +1 -1
  110. package/lib/cjs-es6/persisters.cjs.gz +0 -0
  111. package/lib/cjs-es6/queries.cjs +1 -1
  112. package/lib/cjs-es6/queries.cjs.gz +0 -0
  113. package/lib/cjs-es6/relationships.cjs +1 -1
  114. package/lib/cjs-es6/relationships.cjs.gz +0 -0
  115. package/lib/cjs-es6/store.cjs +1 -1
  116. package/lib/cjs-es6/store.cjs.gz +0 -0
  117. package/lib/cjs-es6/synchronizers/synchronizer-local.cjs +1 -0
  118. package/lib/cjs-es6/synchronizers/synchronizer-local.cjs.gz +0 -0
  119. package/lib/cjs-es6/synchronizers/synchronizer-ws-client.cjs +1 -0
  120. package/lib/cjs-es6/synchronizers/synchronizer-ws-client.cjs.gz +0 -0
  121. package/lib/cjs-es6/synchronizers/synchronizer-ws-server.cjs +1 -0
  122. package/lib/cjs-es6/synchronizers/synchronizer-ws-server.cjs.gz +0 -0
  123. package/lib/cjs-es6/synchronizers.cjs +1 -0
  124. package/lib/cjs-es6/synchronizers.cjs.gz +0 -0
  125. package/lib/cjs-es6/tinybase.cjs +1 -1
  126. package/lib/cjs-es6/tinybase.cjs.gz +0 -0
  127. package/lib/cjs-es6/tools.cjs +1 -1
  128. package/lib/cjs-es6/tools.cjs.gz +0 -0
  129. package/lib/cjs-es6/ui-react-dom-debug.cjs +1 -1
  130. package/lib/cjs-es6/ui-react-dom-debug.cjs.gz +0 -0
  131. package/lib/cjs-es6/ui-react-dom.cjs +1 -1
  132. package/lib/cjs-es6/ui-react-dom.cjs.gz +0 -0
  133. package/lib/cjs-es6/ui-react.cjs +1 -1
  134. package/lib/cjs-es6/ui-react.cjs.gz +0 -0
  135. package/lib/debug/checkpoints.js +3 -1
  136. package/lib/debug/indexes.js +3 -1
  137. package/lib/debug/mergeable-store.js +2230 -0
  138. package/lib/debug/metrics.js +3 -1
  139. package/lib/debug/persisters/persister-automerge.js +110 -86
  140. package/lib/debug/persisters/persister-browser.js +94 -57
  141. package/lib/debug/persisters/persister-cr-sqlite-wasm.js +168 -106
  142. package/lib/debug/persisters/persister-electric-sql.js +168 -106
  143. package/lib/debug/persisters/persister-expo-sqlite-next.js +168 -106
  144. package/lib/debug/persisters/persister-expo-sqlite.js +168 -106
  145. package/lib/debug/persisters/persister-file.js +93 -57
  146. package/lib/debug/persisters/persister-indexed-db.js +90 -56
  147. package/lib/debug/persisters/persister-libsql.js +913 -0
  148. package/lib/debug/persisters/persister-partykit-client.js +89 -59
  149. package/lib/debug/persisters/persister-partykit-server.js +17 -25
  150. package/lib/debug/persisters/persister-powersync.js +928 -0
  151. package/lib/debug/persisters/persister-remote.js +85 -53
  152. package/lib/debug/persisters/persister-sqlite-wasm.js +168 -106
  153. package/lib/debug/persisters/persister-sqlite3.js +168 -106
  154. package/lib/debug/persisters/persister-yjs.js +108 -83
  155. package/lib/debug/persisters.js +81 -50
  156. package/lib/debug/queries.js +9 -6
  157. package/lib/debug/relationships.js +3 -1
  158. package/lib/debug/store.js +147 -126
  159. package/lib/debug/synchronizers/synchronizer-local.js +559 -0
  160. package/lib/debug/synchronizers/synchronizer-ws-client.js +586 -0
  161. package/lib/debug/synchronizers/synchronizer-ws-server.js +96 -0
  162. package/lib/debug/synchronizers.js +519 -0
  163. package/lib/debug/tinybase.js +1027 -174
  164. package/lib/debug/tools.js +22 -21
  165. package/lib/debug/ui-react-dom.js +275 -213
  166. package/lib/debug/ui-react.js +55 -6
  167. package/lib/es6/checkpoints.js +1 -1
  168. package/lib/es6/checkpoints.js.gz +0 -0
  169. package/lib/es6/indexes.js +1 -1
  170. package/lib/es6/indexes.js.gz +0 -0
  171. package/lib/es6/mergeable-store.js +1 -0
  172. package/lib/es6/mergeable-store.js.gz +0 -0
  173. package/lib/es6/metrics.js +1 -1
  174. package/lib/es6/metrics.js.gz +0 -0
  175. package/lib/es6/persisters/persister-automerge.js +1 -1
  176. package/lib/es6/persisters/persister-automerge.js.gz +0 -0
  177. package/lib/es6/persisters/persister-browser.js +1 -1
  178. package/lib/es6/persisters/persister-browser.js.gz +0 -0
  179. package/lib/es6/persisters/persister-cr-sqlite-wasm.js +1 -1
  180. package/lib/es6/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
  181. package/lib/es6/persisters/persister-electric-sql.js +1 -1
  182. package/lib/es6/persisters/persister-electric-sql.js.gz +0 -0
  183. package/lib/es6/persisters/persister-expo-sqlite-next.js +1 -1
  184. package/lib/es6/persisters/persister-expo-sqlite-next.js.gz +0 -0
  185. package/lib/es6/persisters/persister-expo-sqlite.js +1 -1
  186. package/lib/es6/persisters/persister-expo-sqlite.js.gz +0 -0
  187. package/lib/es6/persisters/persister-file.js +1 -1
  188. package/lib/es6/persisters/persister-file.js.gz +0 -0
  189. package/lib/es6/persisters/persister-indexed-db.js +1 -1
  190. package/lib/es6/persisters/persister-indexed-db.js.gz +0 -0
  191. package/lib/es6/persisters/persister-libsql.js +1 -0
  192. package/lib/es6/persisters/persister-libsql.js.gz +0 -0
  193. package/lib/es6/persisters/persister-partykit-client.js +1 -1
  194. package/lib/es6/persisters/persister-partykit-client.js.gz +0 -0
  195. package/lib/es6/persisters/persister-partykit-server.js +1 -1
  196. package/lib/es6/persisters/persister-partykit-server.js.gz +0 -0
  197. package/lib/es6/persisters/persister-powersync.js +1 -0
  198. package/lib/es6/persisters/persister-powersync.js.gz +0 -0
  199. package/lib/es6/persisters/persister-remote.js +1 -1
  200. package/lib/es6/persisters/persister-remote.js.gz +0 -0
  201. package/lib/es6/persisters/persister-sqlite-wasm.js +1 -1
  202. package/lib/es6/persisters/persister-sqlite-wasm.js.gz +0 -0
  203. package/lib/es6/persisters/persister-sqlite3.js +1 -1
  204. package/lib/es6/persisters/persister-sqlite3.js.gz +0 -0
  205. package/lib/es6/persisters/persister-yjs.js +1 -1
  206. package/lib/es6/persisters/persister-yjs.js.gz +0 -0
  207. package/lib/es6/persisters.js +1 -1
  208. package/lib/es6/persisters.js.gz +0 -0
  209. package/lib/es6/queries.js +1 -1
  210. package/lib/es6/queries.js.gz +0 -0
  211. package/lib/es6/relationships.js +1 -1
  212. package/lib/es6/relationships.js.gz +0 -0
  213. package/lib/es6/store.js +1 -1
  214. package/lib/es6/store.js.gz +0 -0
  215. package/lib/es6/synchronizers/synchronizer-local.js +1 -0
  216. package/lib/es6/synchronizers/synchronizer-local.js.gz +0 -0
  217. package/lib/es6/synchronizers/synchronizer-ws-client.js +1 -0
  218. package/lib/es6/synchronizers/synchronizer-ws-client.js.gz +0 -0
  219. package/lib/es6/synchronizers/synchronizer-ws-server.js +1 -0
  220. package/lib/es6/synchronizers/synchronizer-ws-server.js.gz +0 -0
  221. package/lib/es6/synchronizers.js +1 -0
  222. package/lib/es6/synchronizers.js.gz +0 -0
  223. package/lib/es6/tinybase.js +1 -1
  224. package/lib/es6/tinybase.js.gz +0 -0
  225. package/lib/es6/tools.js +1 -1
  226. package/lib/es6/tools.js.gz +0 -0
  227. package/lib/es6/ui-react-dom-debug.js +1 -1
  228. package/lib/es6/ui-react-dom-debug.js.gz +0 -0
  229. package/lib/es6/ui-react-dom.js +1 -1
  230. package/lib/es6/ui-react-dom.js.gz +0 -0
  231. package/lib/es6/ui-react.js +1 -1
  232. package/lib/es6/ui-react.js.gz +0 -0
  233. package/lib/indexes.js +1 -1
  234. package/lib/indexes.js.gz +0 -0
  235. package/lib/mergeable-store.js +1 -0
  236. package/lib/mergeable-store.js.gz +0 -0
  237. package/lib/metrics.js +1 -1
  238. package/lib/metrics.js.gz +0 -0
  239. package/lib/persisters/persister-automerge.js +1 -1
  240. package/lib/persisters/persister-automerge.js.gz +0 -0
  241. package/lib/persisters/persister-browser.js +1 -1
  242. package/lib/persisters/persister-browser.js.gz +0 -0
  243. package/lib/persisters/persister-cr-sqlite-wasm.js +1 -1
  244. package/lib/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
  245. package/lib/persisters/persister-electric-sql.js +1 -1
  246. package/lib/persisters/persister-electric-sql.js.gz +0 -0
  247. package/lib/persisters/persister-expo-sqlite-next.js +1 -1
  248. package/lib/persisters/persister-expo-sqlite-next.js.gz +0 -0
  249. package/lib/persisters/persister-expo-sqlite.js +1 -1
  250. package/lib/persisters/persister-expo-sqlite.js.gz +0 -0
  251. package/lib/persisters/persister-file.js +1 -1
  252. package/lib/persisters/persister-file.js.gz +0 -0
  253. package/lib/persisters/persister-indexed-db.js +1 -1
  254. package/lib/persisters/persister-indexed-db.js.gz +0 -0
  255. package/lib/persisters/persister-libsql.js +1 -0
  256. package/lib/persisters/persister-libsql.js.gz +0 -0
  257. package/lib/persisters/persister-partykit-client.js +1 -1
  258. package/lib/persisters/persister-partykit-client.js.gz +0 -0
  259. package/lib/persisters/persister-partykit-server.js +1 -1
  260. package/lib/persisters/persister-partykit-server.js.gz +0 -0
  261. package/lib/persisters/persister-powersync.js +1 -0
  262. package/lib/persisters/persister-powersync.js.gz +0 -0
  263. package/lib/persisters/persister-remote.js +1 -1
  264. package/lib/persisters/persister-remote.js.gz +0 -0
  265. package/lib/persisters/persister-sqlite-wasm.js +1 -1
  266. package/lib/persisters/persister-sqlite-wasm.js.gz +0 -0
  267. package/lib/persisters/persister-sqlite3.js +1 -1
  268. package/lib/persisters/persister-sqlite3.js.gz +0 -0
  269. package/lib/persisters/persister-yjs.js +1 -1
  270. package/lib/persisters/persister-yjs.js.gz +0 -0
  271. package/lib/persisters.js +1 -1
  272. package/lib/persisters.js.gz +0 -0
  273. package/lib/queries.js +1 -1
  274. package/lib/queries.js.gz +0 -0
  275. package/lib/relationships.js +1 -1
  276. package/lib/relationships.js.gz +0 -0
  277. package/lib/store.js +1 -1
  278. package/lib/store.js.gz +0 -0
  279. package/lib/synchronizers/synchronizer-local.js +1 -0
  280. package/lib/synchronizers/synchronizer-local.js.gz +0 -0
  281. package/lib/synchronizers/synchronizer-ws-client.js +1 -0
  282. package/lib/synchronizers/synchronizer-ws-client.js.gz +0 -0
  283. package/lib/synchronizers/synchronizer-ws-server.js +1 -0
  284. package/lib/synchronizers/synchronizer-ws-server.js.gz +0 -0
  285. package/lib/synchronizers.js +1 -0
  286. package/lib/synchronizers.js.gz +0 -0
  287. package/lib/tinybase.js +1 -1
  288. package/lib/tinybase.js.gz +0 -0
  289. package/lib/tools.js +1 -1
  290. package/lib/tools.js.gz +0 -0
  291. package/lib/types/checkpoints.d.ts +2 -2
  292. package/lib/types/indexes.d.ts +2 -2
  293. package/lib/types/mergeable-store.d.ts +214 -0
  294. package/lib/types/metrics.d.ts +2 -2
  295. package/lib/types/persisters/persister-automerge.d.ts +11 -7
  296. package/lib/types/persisters/persister-browser.d.ts +13 -4
  297. package/lib/types/persisters/persister-cr-sqlite-wasm.d.ts +4 -0
  298. package/lib/types/persisters/persister-electric-sql.d.ts +4 -0
  299. package/lib/types/persisters/persister-expo-sqlite-next.d.ts +4 -0
  300. package/lib/types/persisters/persister-expo-sqlite.d.ts +4 -0
  301. package/lib/types/persisters/persister-file.d.ts +7 -2
  302. package/lib/types/persisters/persister-indexed-db.d.ts +4 -0
  303. package/lib/types/persisters/persister-libsql.d.ts +142 -0
  304. package/lib/types/persisters/persister-partykit-client.d.ts +4 -0
  305. package/lib/types/persisters/persister-partykit-server.d.ts +12 -8
  306. package/lib/types/persisters/persister-powersync.d.ts +157 -0
  307. package/lib/types/persisters/persister-remote.d.ts +4 -0
  308. package/lib/types/persisters/persister-sqlite-wasm.d.ts +4 -0
  309. package/lib/types/persisters/persister-sqlite3.d.ts +4 -0
  310. package/lib/types/persisters/persister-yjs.d.ts +6 -2
  311. package/lib/types/persisters.d.ts +125 -48
  312. package/lib/types/queries.d.ts +2 -2
  313. package/lib/types/relationships.d.ts +2 -2
  314. package/lib/types/store.d.ts +275 -187
  315. package/lib/types/synchronizers/synchronizer-local.d.ts +27 -0
  316. package/lib/types/synchronizers/synchronizer-ws-client.d.ts +35 -0
  317. package/lib/types/synchronizers/synchronizer-ws-server.d.ts +36 -0
  318. package/lib/types/synchronizers.d.ts +132 -0
  319. package/lib/types/tinybase.d.ts +10 -8
  320. package/lib/types/tools.d.ts +4 -4
  321. package/lib/types/ui-react.d.ts +160 -9
  322. package/lib/types/with-schemas/checkpoints.d.ts +2 -2
  323. package/lib/types/with-schemas/indexes.d.ts +2 -2
  324. package/lib/types/with-schemas/internal/store.d.ts +4 -0
  325. package/lib/types/with-schemas/mergeable-store.d.ts +492 -0
  326. package/lib/types/with-schemas/metrics.d.ts +2 -2
  327. package/lib/types/with-schemas/persisters/persister-automerge.d.ts +12 -8
  328. package/lib/types/with-schemas/persisters/persister-browser.d.ts +17 -8
  329. package/lib/types/with-schemas/persisters/persister-cr-sqlite-wasm.d.ts +5 -1
  330. package/lib/types/with-schemas/persisters/persister-electric-sql.d.ts +5 -1
  331. package/lib/types/with-schemas/persisters/persister-expo-sqlite-next.d.ts +5 -1
  332. package/lib/types/with-schemas/persisters/persister-expo-sqlite.d.ts +5 -1
  333. package/lib/types/with-schemas/persisters/persister-file.d.ts +9 -4
  334. package/lib/types/with-schemas/persisters/persister-indexed-db.d.ts +5 -1
  335. package/lib/types/with-schemas/persisters/persister-libsql.d.ts +155 -0
  336. package/lib/types/with-schemas/persisters/persister-partykit-client.d.ts +5 -1
  337. package/lib/types/with-schemas/persisters/persister-partykit-server.d.ts +15 -11
  338. package/lib/types/with-schemas/persisters/persister-powersync.d.ts +170 -0
  339. package/lib/types/with-schemas/persisters/persister-remote.d.ts +5 -1
  340. package/lib/types/with-schemas/persisters/persister-sqlite-wasm.d.ts +5 -1
  341. package/lib/types/with-schemas/persisters/persister-sqlite3.d.ts +5 -1
  342. package/lib/types/with-schemas/persisters/persister-yjs.d.ts +7 -3
  343. package/lib/types/with-schemas/persisters.d.ts +161 -101
  344. package/lib/types/with-schemas/queries.d.ts +3 -3
  345. package/lib/types/with-schemas/relationships.d.ts +2 -2
  346. package/lib/types/with-schemas/store.d.ts +483 -345
  347. package/lib/types/with-schemas/synchronizers/synchronizer-local.d.ts +29 -0
  348. package/lib/types/with-schemas/synchronizers/synchronizer-ws-client.d.ts +41 -0
  349. package/lib/types/with-schemas/synchronizers/synchronizer-ws-server.d.ts +36 -0
  350. package/lib/types/with-schemas/synchronizers.d.ts +146 -0
  351. package/lib/types/with-schemas/tinybase.d.ts +9 -8
  352. package/lib/types/with-schemas/tools.d.ts +4 -4
  353. package/lib/types/with-schemas/ui-react.d.ts +177 -9
  354. package/lib/ui-react-dom.js +1 -1
  355. package/lib/ui-react-dom.js.gz +0 -0
  356. package/lib/ui-react.js +1 -1
  357. package/lib/ui-react.js.gz +0 -0
  358. package/lib/umd/checkpoints.js +1 -1
  359. package/lib/umd/checkpoints.js.gz +0 -0
  360. package/lib/umd/indexes.js +1 -1
  361. package/lib/umd/indexes.js.gz +0 -0
  362. package/lib/umd/mergeable-store.js +1 -0
  363. package/lib/umd/mergeable-store.js.gz +0 -0
  364. package/lib/umd/metrics.js +1 -1
  365. package/lib/umd/metrics.js.gz +0 -0
  366. package/lib/umd/persisters/persister-automerge.js +1 -1
  367. package/lib/umd/persisters/persister-automerge.js.gz +0 -0
  368. package/lib/umd/persisters/persister-browser.js +1 -1
  369. package/lib/umd/persisters/persister-browser.js.gz +0 -0
  370. package/lib/umd/persisters/persister-cr-sqlite-wasm.js +1 -1
  371. package/lib/umd/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
  372. package/lib/umd/persisters/persister-electric-sql.js +1 -1
  373. package/lib/umd/persisters/persister-electric-sql.js.gz +0 -0
  374. package/lib/umd/persisters/persister-expo-sqlite-next.js +1 -1
  375. package/lib/umd/persisters/persister-expo-sqlite-next.js.gz +0 -0
  376. package/lib/umd/persisters/persister-expo-sqlite.js +1 -1
  377. package/lib/umd/persisters/persister-expo-sqlite.js.gz +0 -0
  378. package/lib/umd/persisters/persister-file.js +1 -1
  379. package/lib/umd/persisters/persister-file.js.gz +0 -0
  380. package/lib/umd/persisters/persister-indexed-db.js +1 -1
  381. package/lib/umd/persisters/persister-indexed-db.js.gz +0 -0
  382. package/lib/umd/persisters/persister-libsql.js +1 -0
  383. package/lib/umd/persisters/persister-libsql.js.gz +0 -0
  384. package/lib/umd/persisters/persister-partykit-client.js +1 -1
  385. package/lib/umd/persisters/persister-partykit-client.js.gz +0 -0
  386. package/lib/umd/persisters/persister-partykit-server.js +1 -1
  387. package/lib/umd/persisters/persister-partykit-server.js.gz +0 -0
  388. package/lib/umd/persisters/persister-powersync.js +1 -0
  389. package/lib/umd/persisters/persister-powersync.js.gz +0 -0
  390. package/lib/umd/persisters/persister-remote.js +1 -1
  391. package/lib/umd/persisters/persister-remote.js.gz +0 -0
  392. package/lib/umd/persisters/persister-sqlite-wasm.js +1 -1
  393. package/lib/umd/persisters/persister-sqlite-wasm.js.gz +0 -0
  394. package/lib/umd/persisters/persister-sqlite3.js +1 -1
  395. package/lib/umd/persisters/persister-sqlite3.js.gz +0 -0
  396. package/lib/umd/persisters/persister-yjs.js +1 -1
  397. package/lib/umd/persisters/persister-yjs.js.gz +0 -0
  398. package/lib/umd/persisters.js +1 -1
  399. package/lib/umd/persisters.js.gz +0 -0
  400. package/lib/umd/queries.js +1 -1
  401. package/lib/umd/queries.js.gz +0 -0
  402. package/lib/umd/relationships.js +1 -1
  403. package/lib/umd/relationships.js.gz +0 -0
  404. package/lib/umd/store.js +1 -1
  405. package/lib/umd/store.js.gz +0 -0
  406. package/lib/umd/synchronizers/synchronizer-local.js +1 -0
  407. package/lib/umd/synchronizers/synchronizer-local.js.gz +0 -0
  408. package/lib/umd/synchronizers/synchronizer-ws-client.js +1 -0
  409. package/lib/umd/synchronizers/synchronizer-ws-client.js.gz +0 -0
  410. package/lib/umd/synchronizers/synchronizer-ws-server.js +1 -0
  411. package/lib/umd/synchronizers/synchronizer-ws-server.js.gz +0 -0
  412. package/lib/umd/synchronizers.js +1 -0
  413. package/lib/umd/synchronizers.js.gz +0 -0
  414. package/lib/umd/tinybase.js +1 -1
  415. package/lib/umd/tinybase.js.gz +0 -0
  416. package/lib/umd/tools.js +1 -1
  417. package/lib/umd/tools.js.gz +0 -0
  418. package/lib/umd/ui-react-dom-debug.js +1 -1
  419. package/lib/umd/ui-react-dom-debug.js.gz +0 -0
  420. package/lib/umd/ui-react-dom.js +1 -1
  421. package/lib/umd/ui-react-dom.js.gz +0 -0
  422. package/lib/umd/ui-react.js +1 -1
  423. package/lib/umd/ui-react.js.gz +0 -0
  424. package/lib/umd-es6/checkpoints.js +1 -1
  425. package/lib/umd-es6/checkpoints.js.gz +0 -0
  426. package/lib/umd-es6/indexes.js +1 -1
  427. package/lib/umd-es6/indexes.js.gz +0 -0
  428. package/lib/umd-es6/mergeable-store.js +1 -0
  429. package/lib/umd-es6/mergeable-store.js.gz +0 -0
  430. package/lib/umd-es6/metrics.js +1 -1
  431. package/lib/umd-es6/metrics.js.gz +0 -0
  432. package/lib/umd-es6/persisters/persister-automerge.js +1 -1
  433. package/lib/umd-es6/persisters/persister-automerge.js.gz +0 -0
  434. package/lib/umd-es6/persisters/persister-browser.js +1 -1
  435. package/lib/umd-es6/persisters/persister-browser.js.gz +0 -0
  436. package/lib/umd-es6/persisters/persister-cr-sqlite-wasm.js +1 -1
  437. package/lib/umd-es6/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
  438. package/lib/umd-es6/persisters/persister-electric-sql.js +1 -1
  439. package/lib/umd-es6/persisters/persister-electric-sql.js.gz +0 -0
  440. package/lib/umd-es6/persisters/persister-expo-sqlite-next.js +1 -1
  441. package/lib/umd-es6/persisters/persister-expo-sqlite-next.js.gz +0 -0
  442. package/lib/umd-es6/persisters/persister-expo-sqlite.js +1 -1
  443. package/lib/umd-es6/persisters/persister-expo-sqlite.js.gz +0 -0
  444. package/lib/umd-es6/persisters/persister-file.js +1 -1
  445. package/lib/umd-es6/persisters/persister-file.js.gz +0 -0
  446. package/lib/umd-es6/persisters/persister-indexed-db.js +1 -1
  447. package/lib/umd-es6/persisters/persister-indexed-db.js.gz +0 -0
  448. package/lib/umd-es6/persisters/persister-libsql.js +1 -0
  449. package/lib/umd-es6/persisters/persister-libsql.js.gz +0 -0
  450. package/lib/umd-es6/persisters/persister-partykit-client.js +1 -1
  451. package/lib/umd-es6/persisters/persister-partykit-client.js.gz +0 -0
  452. package/lib/umd-es6/persisters/persister-partykit-server.js +1 -1
  453. package/lib/umd-es6/persisters/persister-partykit-server.js.gz +0 -0
  454. package/lib/umd-es6/persisters/persister-powersync.js +1 -0
  455. package/lib/umd-es6/persisters/persister-powersync.js.gz +0 -0
  456. package/lib/umd-es6/persisters/persister-remote.js +1 -1
  457. package/lib/umd-es6/persisters/persister-remote.js.gz +0 -0
  458. package/lib/umd-es6/persisters/persister-sqlite-wasm.js +1 -1
  459. package/lib/umd-es6/persisters/persister-sqlite-wasm.js.gz +0 -0
  460. package/lib/umd-es6/persisters/persister-sqlite3.js +1 -1
  461. package/lib/umd-es6/persisters/persister-sqlite3.js.gz +0 -0
  462. package/lib/umd-es6/persisters/persister-yjs.js +1 -1
  463. package/lib/umd-es6/persisters/persister-yjs.js.gz +0 -0
  464. package/lib/umd-es6/persisters.js +1 -1
  465. package/lib/umd-es6/persisters.js.gz +0 -0
  466. package/lib/umd-es6/queries.js +1 -1
  467. package/lib/umd-es6/queries.js.gz +0 -0
  468. package/lib/umd-es6/relationships.js +1 -1
  469. package/lib/umd-es6/relationships.js.gz +0 -0
  470. package/lib/umd-es6/store.js +1 -1
  471. package/lib/umd-es6/store.js.gz +0 -0
  472. package/lib/umd-es6/synchronizers/synchronizer-local.js +1 -0
  473. package/lib/umd-es6/synchronizers/synchronizer-local.js.gz +0 -0
  474. package/lib/umd-es6/synchronizers/synchronizer-ws-client.js +1 -0
  475. package/lib/umd-es6/synchronizers/synchronizer-ws-client.js.gz +0 -0
  476. package/lib/umd-es6/synchronizers/synchronizer-ws-server.js +1 -0
  477. package/lib/umd-es6/synchronizers/synchronizer-ws-server.js.gz +0 -0
  478. package/lib/umd-es6/synchronizers.js +1 -0
  479. package/lib/umd-es6/synchronizers.js.gz +0 -0
  480. package/lib/umd-es6/tinybase.js +1 -1
  481. package/lib/umd-es6/tinybase.js.gz +0 -0
  482. package/lib/umd-es6/tools.js +1 -1
  483. package/lib/umd-es6/tools.js.gz +0 -0
  484. package/lib/umd-es6/ui-react-dom-debug.js +1 -1
  485. package/lib/umd-es6/ui-react-dom-debug.js.gz +0 -0
  486. package/lib/umd-es6/ui-react-dom.js +1 -1
  487. package/lib/umd-es6/ui-react-dom.js.gz +0 -0
  488. package/lib/umd-es6/ui-react.js +1 -1
  489. package/lib/umd-es6/ui-react.js.gz +0 -0
  490. package/package.json +65 -45
  491. 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);
@@ -71,9 +76,7 @@ const arrayShift = (array) => array.shift();
71
76
  const object = Object;
72
77
  const getPrototypeOf = (obj) => object.getPrototypeOf(obj);
73
78
  const objEntries = object.entries;
74
- const objIds = object.keys;
75
79
  const objFrozen = object.isFrozen;
76
- const objFreeze = object.freeze;
77
80
  const isObject = (obj) =>
78
81
  !isUndefined(obj) &&
79
82
  ifNotUndefined(
@@ -84,16 +87,43 @@ const isObject = (obj) =>
84
87
  /* istanbul ignore next */
85
88
  () => true,
86
89
  );
87
- const objGet = (obj, id) => ifNotUndefined(obj, (obj2) => obj2[id]);
88
- 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;
89
94
  const objDel = (obj, id) => {
90
95
  delete obj[id];
91
96
  return obj;
92
97
  };
93
- const objMap = (obj, cb) =>
98
+ const objForEach = (obj, cb) =>
99
+ arrayForEach(objEntries(obj), ([id, value]) => cb(value, id));
100
+ const objToArray = (obj, cb) =>
94
101
  arrayMap(objEntries(obj), ([id, value]) => cb(value, id));
95
102
  const objSize = (obj) => size(objIds(obj));
96
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
+ };
97
127
 
98
128
  const collSizeN = (collSizer) => (coll) =>
99
129
  arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
@@ -117,35 +147,41 @@ const mapMap = (coll, cb) =>
117
147
  arrayMap([...(coll?.entries() ?? [])], ([key, value]) => cb(value, key));
118
148
  const mapSet = (map, key, value) =>
119
149
  isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
120
- const mapEnsure = (map, key, getDefaultValue) => {
150
+ const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
121
151
  if (!collHas(map, key)) {
122
152
  mapSet(map, key, getDefaultValue());
153
+ } else {
154
+ hadExistingValue?.(mapGet(map, key));
123
155
  }
124
156
  return mapGet(map, key);
125
157
  };
126
158
  const mapMatch = (map, obj, set, del = mapSet) => {
127
- objMap(obj, (value, id) => set(map, id, value));
159
+ objToArray(obj, (value, id) => set(map, id, value));
128
160
  mapForEach(map, (id) => (objHas(obj, id) ? 0 : del(map, id)));
129
161
  return map;
130
162
  };
131
- const mapToObj = (map, mapValue, excludeValue) => {
163
+ const mapToObj = (map, valueMapper, excludeMapValue, excludeObjValue) => {
132
164
  const obj = {};
133
- collForEach(map, (value, id) => {
134
- const mappedValue = mapValue ? mapValue(value, id) : value;
135
- 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
+ }
136
170
  });
137
171
  return obj;
138
172
  };
139
- const mapToObj2 = (map, mapValue, excludeValue) =>
173
+ const mapToObj2 = (map, valueMapper, excludeMapValue) =>
140
174
  mapToObj(
141
175
  map,
142
- (childMap) => mapToObj(childMap, mapValue, excludeValue),
176
+ (childMap) => mapToObj(childMap, valueMapper, excludeMapValue),
177
+ collIsEmpty,
143
178
  objIsEmpty,
144
179
  );
145
- const mapToObj3 = (map, mapValue, excludeValue) =>
180
+ const mapToObj3 = (map, valueMapper, excludeMapValue) =>
146
181
  mapToObj(
147
182
  map,
148
- (childMap) => mapToObj2(childMap, mapValue, excludeValue),
183
+ (childMap) => mapToObj2(childMap, valueMapper, excludeMapValue),
184
+ collIsEmpty,
149
185
  objIsEmpty,
150
186
  );
151
187
  const mapClone = (map, mapValue) => {
@@ -177,12 +213,15 @@ const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
177
213
  },
178
214
  );
179
215
 
180
- const getCellOrValueType = (cell) => {
181
- const type = getTypeOf(cell);
182
- 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))
183
220
  ? type
184
221
  : void 0;
185
222
  };
223
+ const isCellOrValueOrNullOrUndefined = (cellOrValue) =>
224
+ isUndefined(cellOrValue) || !isUndefined(getCellOrValueType(cellOrValue));
186
225
  const setOrDelCell = (store, tableId, rowId, cellId, cell) =>
187
226
  isUndefined(cell)
188
227
  ? store.delCell(tableId, rowId, cellId, true)
@@ -1079,6 +1118,24 @@ const createMetrics = getCreateFunction((store) => {
1079
1118
 
1080
1119
  const scheduleRunning = mapNew();
1081
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
+ ];
1082
1139
  const createCustomPersister = (
1083
1140
  store,
1084
1141
  getPersisted,
@@ -1086,18 +1143,25 @@ const createCustomPersister = (
1086
1143
  addPersisterListener,
1087
1144
  delPersisterListener,
1088
1145
  onIgnoredError,
1089
- [getThing, thing] = [],
1146
+ supportsMergeableStore,
1147
+ extra = {},
1090
1148
  scheduleId = [],
1091
1149
  ) => {
1092
- let listenerId;
1093
1150
  let loadSave = 0;
1094
1151
  let loads = 0;
1095
1152
  let saves = 0;
1096
- let listening = 0;
1097
1153
  let action;
1098
- let listeningHandle;
1154
+ let autoLoadHandle;
1155
+ let autoSaveListenerId;
1099
1156
  mapEnsure(scheduleRunning, scheduleId, () => 0);
1100
1157
  mapEnsure(scheduleActions, scheduleId, () => []);
1158
+ const [
1159
+ isMergeableStore,
1160
+ getContent,
1161
+ getChanges,
1162
+ hasChanges,
1163
+ setDefaultContent,
1164
+ ] = getStoreFunctions(supportsMergeableStore, store);
1101
1165
  const run = async () => {
1102
1166
  /* istanbul ignore else */
1103
1167
  if (!mapGet(scheduleRunning, scheduleId)) {
@@ -1129,48 +1193,54 @@ const createCustomPersister = (
1129
1193
  }
1130
1194
  return persister;
1131
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
+ };
1132
1205
  const persister = {
1133
- load: async (initialTables, initialValues) =>
1206
+ load: async (initialContent) =>
1134
1207
  await loadLock(async () => {
1135
1208
  try {
1136
- store.setContent(await getPersisted());
1137
- } catch {
1138
- store.setContent([initialTables, initialValues]);
1209
+ setContentOrChanges(await getPersisted());
1210
+ } catch (error) {
1211
+ onIgnoredError?.(error);
1212
+ if (initialContent) {
1213
+ setDefaultContent(initialContent);
1214
+ }
1139
1215
  }
1140
1216
  }),
1141
- startAutoLoad: async (initialTables = {}, initialValues = {}) => {
1142
- persister.stopAutoLoad();
1143
- await persister.load(initialTables, initialValues);
1144
- listening = 1;
1145
- listeningHandle = addPersisterListener(
1146
- async (getContent, getTransactionChanges) => {
1147
- if (getTransactionChanges) {
1148
- const transactionChanges = getTransactionChanges();
1149
- await loadLock(async () =>
1150
- store.setTransactionChanges(transactionChanges),
1151
- );
1152
- } else {
1153
- await loadLock(async () => {
1154
- try {
1155
- store.setContent(getContent?.() ?? (await getPersisted()));
1156
- } catch (error) {
1157
- onIgnoredError?.(error);
1158
- }
1159
- });
1160
- }
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
+ });
1161
1231
  },
1162
1232
  );
1163
1233
  return persister;
1164
1234
  },
1165
1235
  stopAutoLoad: () => {
1166
- if (listening) {
1167
- delPersisterListener(listeningHandle);
1168
- listeningHandle = void 0;
1169
- listening = 0;
1236
+ if (autoLoadHandle) {
1237
+ delPersisterListener(autoLoadHandle);
1238
+ autoLoadHandle = void 0;
1170
1239
  }
1171
1240
  return persister;
1172
1241
  },
1173
- save: async (getTransactionChanges) => {
1242
+ isAutoLoading: () => !isUndefined(autoLoadHandle),
1243
+ save: async (getChanges2) => {
1174
1244
  /* istanbul ignore else */
1175
1245
  if (loadSave != 1) {
1176
1246
  loadSave = 2;
@@ -1179,7 +1249,7 @@ const createCustomPersister = (
1179
1249
  }
1180
1250
  await persister.schedule(async () => {
1181
1251
  try {
1182
- await setPersisted(store.getContent, getTransactionChanges);
1252
+ await setPersisted(getContent, getChanges2);
1183
1253
  } catch (error) {
1184
1254
  /* istanbul ignore next */
1185
1255
  onIgnoredError?.(error);
@@ -1191,21 +1261,20 @@ const createCustomPersister = (
1191
1261
  },
1192
1262
  startAutoSave: async () => {
1193
1263
  await persister.stopAutoSave().save();
1194
- listenerId = store.addDidFinishTransactionListener(
1195
- (_store, getTransactionChanges) => {
1196
- const [tableChanges, valueChanges] = getTransactionChanges();
1197
- if (!objIsEmpty(tableChanges) || !objIsEmpty(valueChanges)) {
1198
- persister.save(() => [tableChanges, valueChanges]);
1199
- }
1200
- },
1201
- );
1264
+ autoSaveListenerId = store.addDidFinishTransactionListener(() => {
1265
+ const changes = getChanges();
1266
+ if (hasChanges(changes)) {
1267
+ persister.save(() => changes);
1268
+ }
1269
+ });
1202
1270
  return persister;
1203
1271
  },
1204
1272
  stopAutoSave: () => {
1205
- ifNotUndefined(listenerId, store.delListener);
1206
- listenerId = void 0;
1273
+ ifNotUndefined(autoSaveListenerId, store.delListener);
1274
+ autoSaveListenerId = void 0;
1207
1275
  return persister;
1208
1276
  },
1277
+ isAutoSaving: () => !isUndefined(autoSaveListenerId),
1209
1278
  schedule: async (...actions) => {
1210
1279
  arrayPush(mapGet(scheduleActions, scheduleId), ...actions);
1211
1280
  await run();
@@ -1214,13 +1283,325 @@ const createCustomPersister = (
1214
1283
  getStore: () => store,
1215
1284
  destroy: () => persister.stopAutoLoad().stopAutoSave(),
1216
1285
  getStats: () => ({loads, saves}),
1286
+ ...extra,
1217
1287
  };
1218
- if (getThing) {
1219
- persister[getThing] = () => thing;
1220
- }
1221
1288
  return objFreeze(persister);
1222
1289
  };
1223
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
+
1224
1605
  const createQueries = getCreateFunction((store) => {
1225
1606
  const createStore = store.createStore;
1226
1607
  const preStore = createStore();
@@ -1648,7 +2029,7 @@ const createQueries = getCreateFunction((store) => {
1648
2029
  destroy,
1649
2030
  getListenerStats,
1650
2031
  };
1651
- objMap(
2032
+ objToArray(
1652
2033
  {
1653
2034
  [TABLE]: [1, 1],
1654
2035
  [TABLE + CELL_IDS]: [0, 1],
@@ -1875,24 +2256,12 @@ const pairNewMap = () => [mapNew(), mapNew()];
1875
2256
  const pairClone = (array) => [...array];
1876
2257
  const pairIsEqual = ([entry1, entry2]) => entry1 === entry2;
1877
2258
 
1878
- const jsonString = (obj) =>
2259
+ const jsonStringWithMap = (obj) =>
1879
2260
  JSON.stringify(obj, (_key, value) =>
1880
2261
  isInstanceOf(value, Map) ? object.fromEntries([...value]) : value,
1881
2262
  );
1882
2263
  const jsonParse = JSON.parse;
1883
2264
 
1884
- const validate = (obj, validateChild, onInvalidObj) => {
1885
- if (isUndefined(obj) || !isObject(obj) || objIsEmpty(obj) || objFrozen(obj)) {
1886
- onInvalidObj?.();
1887
- return false;
1888
- }
1889
- objMap(obj, (child, id2) => {
1890
- if (!validateChild(child, id2)) {
1891
- objDel(obj, id2);
1892
- }
1893
- });
1894
- return !objIsEmpty(obj);
1895
- };
1896
2265
  const idsChanged = (changedIds, id2, addedOrRemoved) =>
1897
2266
  mapSet(
1898
2267
  changedIds,
@@ -1902,11 +2271,10 @@ const idsChanged = (changedIds, id2, addedOrRemoved) =>
1902
2271
  const createStore = () => {
1903
2272
  let hasTablesSchema;
1904
2273
  let hasValuesSchema;
1905
- let cellsTouched = false;
1906
- let valuesTouched = false;
1907
2274
  let hadTables = false;
1908
2275
  let hadValues = false;
1909
2276
  let transactions = 0;
2277
+ let internalListeners = [];
1910
2278
  const changedTableIds = mapNew();
1911
2279
  const changedTableCellIds = mapNew();
1912
2280
  const changedRowCount = mapNew();
@@ -1953,13 +2321,13 @@ const createStore = () => {
1953
2321
  const [addListener, callListeners, delListenerImpl, callListenerImpl] =
1954
2322
  getListenerFunctions(() => store);
1955
2323
  const validateTablesSchema = (tableSchema) =>
1956
- validate(tableSchema, (tableSchema2) =>
1957
- validate(tableSchema2, validateCellOrValueSchema),
2324
+ objValidate(tableSchema, (tableSchema2) =>
2325
+ objValidate(tableSchema2, validateCellOrValueSchema),
1958
2326
  );
1959
2327
  const validateValuesSchema = (valuesSchema) =>
1960
- validate(valuesSchema, validateCellOrValueSchema);
2328
+ objValidate(valuesSchema, validateCellOrValueSchema);
1961
2329
  const validateCellOrValueSchema = (schema) => {
1962
- if (!validate(schema, (_child, id2) => arrayHas([TYPE, DEFAULT], id2))) {
2330
+ if (!objValidate(schema, (_child, id2) => arrayHas([TYPE, DEFAULT], id2))) {
1963
2331
  return false;
1964
2332
  }
1965
2333
  const type = schema[TYPE];
@@ -1972,18 +2340,18 @@ const createStore = () => {
1972
2340
  return true;
1973
2341
  };
1974
2342
  const validateTables = (tables) =>
1975
- validate(tables, validateTable, cellInvalid);
2343
+ objValidate(tables, validateTable, cellInvalid);
1976
2344
  const validateTable = (table, tableId) =>
1977
2345
  (!hasTablesSchema ||
1978
2346
  collHas(tablesSchemaMap, tableId) ||
1979
2347
  cellInvalid(tableId)) &&
1980
- validate(
2348
+ objValidate(
1981
2349
  table,
1982
2350
  (row, rowId) => validateRow(tableId, rowId, row),
1983
2351
  () => cellInvalid(tableId),
1984
2352
  );
1985
2353
  const validateRow = (tableId, rowId, row, skipDefaults) =>
1986
- validate(
2354
+ objValidate(
1987
2355
  skipDefaults ? row : addDefaultsToRow(row, tableId, rowId),
1988
2356
  (cell, cellId) =>
1989
2357
  ifNotUndefined(
@@ -2010,7 +2378,7 @@ const createStore = () => {
2010
2378
  ? cellInvalid(tableId, rowId, cellId, cell)
2011
2379
  : cell;
2012
2380
  const validateValues = (values, skipDefaults) =>
2013
- validate(
2381
+ objValidate(
2014
2382
  skipDefaults ? values : addDefaultsToValues(values),
2015
2383
  (value, valueId) =>
2016
2384
  ifNotUndefined(
@@ -2273,16 +2641,20 @@ const createStore = () => {
2273
2641
  addedOrRemoved,
2274
2642
  );
2275
2643
  };
2276
- const cellChanged = (tableId, rowId, cellId, oldCell, newCell) =>
2277
- (mapEnsure(
2644
+ const cellChanged = (tableId, rowId, cellId, oldCell, newCell) => {
2645
+ mapEnsure(
2278
2646
  mapEnsure(mapEnsure(changedCells, tableId, mapNew), rowId, mapNew),
2279
2647
  cellId,
2280
2648
  () => [oldCell, 0],
2281
- )[1] = newCell);
2649
+ )[1] = newCell;
2650
+ internalListeners[3]?.(tableId, rowId, cellId, newCell);
2651
+ };
2282
2652
  const valueIdsChanged = (valueId, addedOrRemoved) =>
2283
2653
  idsChanged(changedValueIds, valueId, addedOrRemoved);
2284
- const valueChanged = (valueId, oldValue, newValue) =>
2285
- (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
+ };
2286
2658
  const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
2287
2659
  arrayPush(
2288
2660
  mapEnsure(
@@ -2548,44 +2920,6 @@ const createStore = () => {
2548
2920
  transaction(() => actions(...arrayMap(args, id)));
2549
2921
  return store;
2550
2922
  };
2551
- const getTransactionChanges = () => [
2552
- mapToObj(
2553
- changedCells,
2554
- (table, tableId) =>
2555
- mapGet(changedTableIds, tableId) === -1
2556
- ? null
2557
- : mapToObj(
2558
- table,
2559
- (row, rowId) =>
2560
- mapGet(mapGet(changedRowIds, tableId), rowId) === -1
2561
- ? null
2562
- : mapToObj(
2563
- row,
2564
- ([, newCell]) => newCell ?? null,
2565
- (_, changedCell) => pairIsEqual(changedCell),
2566
- ),
2567
- objIsEmpty,
2568
- ),
2569
- objIsEmpty,
2570
- ),
2571
- mapToObj(
2572
- changedValues,
2573
- ([, newValue]) => newValue ?? null,
2574
- (_, changedValue) => pairIsEqual(changedValue),
2575
- ),
2576
- ];
2577
- const getTransactionLog = () => ({
2578
- cellsTouched,
2579
- valuesTouched,
2580
- changedCells: mapToObj3(changedCells, pairClone, pairIsEqual),
2581
- invalidCells: mapToObj3(invalidCells),
2582
- changedValues: mapToObj(changedValues, pairClone, pairIsEqual),
2583
- invalidValues: mapToObj(invalidValues),
2584
- changedTableIds: mapToObj(changedTableIds),
2585
- changedRowIds: mapToObj2(changedRowIds),
2586
- changedCellIds: mapToObj3(changedCellIds),
2587
- changedValueIds: mapToObj(changedValueIds),
2588
- });
2589
2923
  const getContent = () => [getTables(), getValues()];
2590
2924
  const getTables = () => mapToObj3(tablesMap);
2591
2925
  const getTableIds = () => mapKeys(tablesMap);
@@ -2629,12 +2963,13 @@ const createStore = () => {
2629
2963
  collHas(mapGet(mapGet(tablesMap, id(tableId)), id(rowId)), id(cellId));
2630
2964
  const hasValues = () => !collIsEmpty(valuesMap);
2631
2965
  const hasValue = (valueId) => collHas(valuesMap, id(valueId));
2632
- const getTablesJson = () => jsonString(tablesMap);
2633
- const getValuesJson = () => jsonString(valuesMap);
2634
- const getJson = () => jsonString([tablesMap, valuesMap]);
2635
- const getTablesSchemaJson = () => jsonString(tablesSchemaMap);
2636
- const getValuesSchemaJson = () => jsonString(valuesSchemaMap);
2637
- 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]);
2638
2973
  const setContent = ([tables, values]) =>
2639
2974
  fluentTransaction(() => {
2640
2975
  (objIsEmpty(tables) ? delTables : setTables)(tables);
@@ -2678,7 +3013,7 @@ const createStore = () => {
2678
3013
  (tableId2, rowId2) => {
2679
3014
  if (validateRow(tableId2, rowId2, partialRow, 1)) {
2680
3015
  const table = getOrCreateTable(tableId2);
2681
- objMap(partialRow, (cell, cellId) =>
3016
+ objToArray(partialRow, (cell, cellId) =>
2682
3017
  setCellIntoDefaultRow(tableId2, table, rowId2, cellId, cell),
2683
3018
  );
2684
3019
  }
@@ -2716,7 +3051,7 @@ const createStore = () => {
2716
3051
  const setPartialValues = (partialValues) =>
2717
3052
  fluentTransaction(() =>
2718
3053
  validateValues(partialValues, 1)
2719
- ? objMap(partialValues, (value, valueId) =>
3054
+ ? objToArray(partialValues, (value, valueId) =>
2720
3055
  setValidValue(valueId, value),
2721
3056
  )
2722
3057
  : 0,
@@ -2733,20 +3068,20 @@ const createStore = () => {
2733
3068
  ),
2734
3069
  valueId,
2735
3070
  );
2736
- const setTransactionChanges = (transactionChanges) =>
3071
+ const applyChanges = (changes) =>
2737
3072
  fluentTransaction(() => {
2738
- objMap(transactionChanges[0], (table, tableId) =>
3073
+ objToArray(changes[0], (table, tableId) =>
2739
3074
  isUndefined(table)
2740
3075
  ? delTable(tableId)
2741
- : objMap(table, (row, rowId) =>
3076
+ : objToArray(table, (row, rowId) =>
2742
3077
  isUndefined(row)
2743
3078
  ? delRow(tableId, rowId)
2744
- : objMap(row, (cell, cellId) =>
3079
+ : objToArray(row, (cell, cellId) =>
2745
3080
  setOrDelCell(store, tableId, rowId, cellId, cell),
2746
3081
  ),
2747
3082
  ),
2748
3083
  );
2749
- objMap(transactionChanges[1], (value, valueId) =>
3084
+ objToArray(changes[1], (value, valueId) =>
2750
3085
  setOrDelValue(store, valueId, value),
2751
3086
  );
2752
3087
  });
@@ -2873,31 +3208,66 @@ const createStore = () => {
2873
3208
  transactions++;
2874
3209
  }
2875
3210
  if (transactions == 1) {
2876
- callListeners(
2877
- startTransactionListeners,
2878
- void 0,
2879
- getTransactionChanges,
2880
- getTransactionLog,
2881
- );
3211
+ internalListeners[0]?.();
3212
+ callListeners(startTransactionListeners, void 0);
2882
3213
  }
2883
3214
  return store;
2884
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
+ ];
2885
3257
  const finishTransaction = (doRollback) => {
2886
3258
  if (transactions > 0) {
2887
3259
  transactions--;
2888
3260
  if (transactions == 0) {
2889
- cellsTouched = !collIsEmpty(changedCells);
2890
- valuesTouched = !collIsEmpty(changedValues);
2891
3261
  transactions = 1;
2892
3262
  callInvalidCellListeners(1);
2893
- if (cellsTouched) {
3263
+ if (!collIsEmpty(changedCells)) {
2894
3264
  callTabularListenersForChanges(1);
2895
3265
  }
2896
3266
  callInvalidValueListeners(1);
2897
- if (valuesTouched) {
3267
+ if (!collIsEmpty(changedValues)) {
2898
3268
  callValuesListenersForChanges(1);
2899
3269
  }
2900
- if (doRollback?.(getTransactionChanges, getTransactionLog)) {
3270
+ if (doRollback?.(store)) {
2901
3271
  collForEach(changedCells, (table, tableId) =>
2902
3272
  collForEach(table, (row, rowId) =>
2903
3273
  collForEach(row, ([oldCell], cellId) =>
@@ -2905,34 +3275,26 @@ const createStore = () => {
2905
3275
  ),
2906
3276
  ),
2907
3277
  );
3278
+ collClear(changedCells);
2908
3279
  collForEach(changedValues, ([oldValue], valueId) =>
2909
3280
  setOrDelValue(store, valueId, oldValue),
2910
3281
  );
2911
- cellsTouched = valuesTouched = false;
3282
+ collClear(changedValues);
2912
3283
  }
2913
- callListeners(
2914
- finishTransactionListeners[0],
2915
- void 0,
2916
- getTransactionChanges,
2917
- getTransactionLog,
2918
- );
3284
+ callListeners(finishTransactionListeners[0], void 0);
2919
3285
  transactions = -1;
2920
3286
  callInvalidCellListeners(0);
2921
- if (cellsTouched) {
3287
+ if (!collIsEmpty(changedCells)) {
2922
3288
  callTabularListenersForChanges(0);
2923
3289
  }
2924
3290
  callInvalidValueListeners(0);
2925
- if (valuesTouched) {
3291
+ if (!collIsEmpty(changedValues)) {
2926
3292
  callValuesListenersForChanges(0);
2927
3293
  }
2928
- callListeners(
2929
- finishTransactionListeners[1],
2930
- void 0,
2931
- getTransactionChanges,
2932
- getTransactionLog,
2933
- );
3294
+ internalListeners[1]?.();
3295
+ callListeners(finishTransactionListeners[1], void 0);
3296
+ internalListeners[2]?.();
2934
3297
  transactions = 0;
2935
- cellsTouched = valuesTouched = false;
2936
3298
  hadTables = hasTables();
2937
3299
  hadValues = hasValues();
2938
3300
  arrayForEach(
@@ -3057,6 +3419,20 @@ const createStore = () => {
3057
3419
  collSize2(startTransactionListeners) +
3058
3420
  pairCollSize2(finishTransactionListeners),
3059
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
+ ]);
3060
3436
  const store = {
3061
3437
  getContent,
3062
3438
  getTables,
@@ -3097,7 +3473,7 @@ const createStore = () => {
3097
3473
  setValues,
3098
3474
  setPartialValues,
3099
3475
  setValue,
3100
- setTransactionChanges,
3476
+ applyChanges,
3101
3477
  setTablesJson,
3102
3478
  setValuesJson,
3103
3479
  setJson,
@@ -3115,6 +3491,8 @@ const createStore = () => {
3115
3491
  delSchema,
3116
3492
  transaction,
3117
3493
  startTransaction,
3494
+ getTransactionChanges,
3495
+ getTransactionLog,
3118
3496
  finishTransaction,
3119
3497
  forEachTable,
3120
3498
  forEachTableCell,
@@ -3132,8 +3510,9 @@ const createStore = () => {
3132
3510
  createStore,
3133
3511
  addListener,
3134
3512
  callListeners,
3513
+ setInternalListeners,
3135
3514
  };
3136
- objMap(
3515
+ objToArray(
3137
3516
  {
3138
3517
  [HAS + TABLES]: [0, hasTablesListeners, [], () => [hasTables()]],
3139
3518
  [TABLES]: [0, tablesListeners],
@@ -3206,10 +3585,484 @@ const createStore = () => {
3206
3585
  return objFreeze(store);
3207
3586
  };
3208
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
+
3209
4060
  export {
3210
4061
  createCheckpoints,
3211
4062
  createCustomPersister,
4063
+ createCustomSynchronizer,
3212
4064
  createIndexes,
4065
+ createMergeableStore,
3213
4066
  createMetrics,
3214
4067
  createQueries,
3215
4068
  createRelationships,