tinybase 5.0.0-beta.1 → 5.0.0-beta.11

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 +167 -131
  140. package/lib/debug/persisters/persister-browser.js +155 -102
  141. package/lib/debug/persisters/persister-cr-sqlite-wasm.js +225 -152
  142. package/lib/debug/persisters/persister-electric-sql.js +225 -152
  143. package/lib/debug/persisters/persister-expo-sqlite-next.js +225 -152
  144. package/lib/debug/persisters/persister-expo-sqlite.js +225 -152
  145. package/lib/debug/persisters/persister-file.js +149 -101
  146. package/lib/debug/persisters/persister-indexed-db.js +146 -100
  147. package/lib/debug/persisters/persister-libsql.js +924 -0
  148. package/lib/debug/persisters/persister-partykit-client.js +146 -104
  149. package/lib/debug/persisters/persister-partykit-server.js +17 -25
  150. package/lib/debug/persisters/persister-powersync.js +939 -0
  151. package/lib/debug/persisters/persister-remote.js +141 -97
  152. package/lib/debug/persisters/persister-sqlite-wasm.js +225 -152
  153. package/lib/debug/persisters/persister-sqlite3.js +225 -152
  154. package/lib/debug/persisters/persister-yjs.js +164 -127
  155. package/lib/debug/persisters.js +137 -94
  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 +571 -0
  160. package/lib/debug/synchronizers/synchronizer-ws-client.js +598 -0
  161. package/lib/debug/synchronizers/synchronizer-ws-server.js +241 -0
  162. package/lib/debug/synchronizers.js +531 -0
  163. package/lib/debug/tinybase.js +1080 -215
  164. package/lib/debug/tools.js +22 -21
  165. package/lib/debug/ui-react-dom.js +336 -258
  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 +162 -59
  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 +57 -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 +193 -121
  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 +57 -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,27 @@ const createMetrics = getCreateFunction((store) => {
1079
1118
 
1080
1119
  const scheduleRunning = mapNew();
1081
1120
  const scheduleActions = mapNew();
1121
+ const getStoreFunctions = (supportedStoreType = 1, store) =>
1122
+ supportedStoreType > 1 && 'getMergeableContent' in store
1123
+ ? [
1124
+ 1,
1125
+ store.getMergeableContent,
1126
+ store.getTransactionMergeableChanges,
1127
+ ([[changedTables], [changedValues]]) =>
1128
+ !objIsEmpty(changedTables) || !objIsEmpty(changedValues),
1129
+ store.setDefaultContent,
1130
+ ]
1131
+ : supportedStoreType != 2
1132
+ ? [
1133
+ 0,
1134
+ store.getContent,
1135
+ store.getTransactionChanges,
1136
+ ([changedTables, changedValues]) =>
1137
+ !objIsEmpty(changedTables) || !objIsEmpty(changedValues),
1138
+ store.setContent,
1139
+ ]
1140
+ : /* istanbul ignore next */
1141
+ 0;
1082
1142
  const createCustomPersister = (
1083
1143
  store,
1084
1144
  getPersisted,
@@ -1086,18 +1146,25 @@ const createCustomPersister = (
1086
1146
  addPersisterListener,
1087
1147
  delPersisterListener,
1088
1148
  onIgnoredError,
1089
- [getThing, thing] = [],
1149
+ supportedStoreType,
1150
+ extra = {},
1090
1151
  scheduleId = [],
1091
1152
  ) => {
1092
- let listenerId;
1093
1153
  let loadSave = 0;
1094
1154
  let loads = 0;
1095
1155
  let saves = 0;
1096
- let listening = 0;
1097
1156
  let action;
1098
- let listeningHandle;
1157
+ let autoLoadHandle;
1158
+ let autoSaveListenerId;
1099
1159
  mapEnsure(scheduleRunning, scheduleId, () => 0);
1100
1160
  mapEnsure(scheduleActions, scheduleId, () => []);
1161
+ const [
1162
+ isMergeableStore,
1163
+ getContent,
1164
+ getChanges,
1165
+ hasChanges,
1166
+ setDefaultContent,
1167
+ ] = getStoreFunctions(supportedStoreType, store);
1101
1168
  const run = async () => {
1102
1169
  /* istanbul ignore else */
1103
1170
  if (!mapGet(scheduleRunning, scheduleId)) {
@@ -1115,110 +1182,436 @@ const createCustomPersister = (
1115
1182
  mapSet(scheduleRunning, scheduleId, 0);
1116
1183
  }
1117
1184
  };
1118
- const loadLock = async (actions) => {
1185
+ const setContentOrChanges = (contentOrChanges) => {
1186
+ (isMergeableStore && isArray(contentOrChanges?.[0])
1187
+ ? contentOrChanges?.[2] === 1
1188
+ ? store.applyMergeableChanges
1189
+ : store.setMergeableContent
1190
+ : contentOrChanges?.[2] === 1
1191
+ ? store.applyChanges
1192
+ : store.setContent)(contentOrChanges);
1193
+ };
1194
+ const load = async (initialContent) => {
1119
1195
  /* istanbul ignore else */
1120
1196
  if (loadSave != 2) {
1121
1197
  loadSave = 1;
1122
1198
  {
1123
1199
  loads++;
1124
1200
  }
1125
- await persister.schedule(async () => {
1126
- await actions();
1201
+ await schedule(async () => {
1202
+ try {
1203
+ setContentOrChanges(await getPersisted());
1204
+ } catch (error) {
1205
+ onIgnoredError?.(error);
1206
+ if (initialContent) {
1207
+ setDefaultContent(initialContent);
1208
+ }
1209
+ }
1127
1210
  loadSave = 0;
1128
1211
  });
1129
1212
  }
1130
1213
  return persister;
1131
1214
  };
1132
- const persister = {
1133
- load: async (initialTables, initialValues) =>
1134
- await loadLock(async () => {
1215
+ const startAutoLoad = async (initialContent) => {
1216
+ await stopAutoLoad().load(initialContent);
1217
+ autoLoadHandle = addPersisterListener(async (content, changes) => {
1218
+ if (changes || content) {
1219
+ /* istanbul ignore else */
1220
+ if (loadSave != 2) {
1221
+ loadSave = 1;
1222
+ {
1223
+ loads++;
1224
+ }
1225
+ setContentOrChanges(changes ?? content);
1226
+ loadSave = 0;
1227
+ }
1228
+ } else {
1229
+ await load();
1230
+ }
1231
+ });
1232
+ return persister;
1233
+ };
1234
+ const stopAutoLoad = () => {
1235
+ if (autoLoadHandle) {
1236
+ delPersisterListener(autoLoadHandle);
1237
+ autoLoadHandle = void 0;
1238
+ }
1239
+ return persister;
1240
+ };
1241
+ const isAutoLoading = () => !isUndefined(autoLoadHandle);
1242
+ const save = async (changes) => {
1243
+ /* istanbul ignore else */
1244
+ if (loadSave != 1) {
1245
+ loadSave = 2;
1246
+ {
1247
+ saves++;
1248
+ }
1249
+ await schedule(async () => {
1135
1250
  try {
1136
- store.setContent(await getPersisted());
1137
- } catch {
1138
- store.setContent([initialTables, initialValues]);
1251
+ await setPersisted(getContent, changes);
1252
+ } catch (error) {
1253
+ /* istanbul ignore next */
1254
+ onIgnoredError?.(error);
1139
1255
  }
1140
- }),
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
- });
1256
+ loadSave = 0;
1257
+ });
1258
+ }
1259
+ return persister;
1260
+ };
1261
+ const startAutoSave = async () => {
1262
+ await stopAutoSave().save();
1263
+ autoSaveListenerId = store.addDidFinishTransactionListener(() => {
1264
+ const changes = getChanges();
1265
+ if (hasChanges(changes)) {
1266
+ save(changes);
1267
+ }
1268
+ });
1269
+ return persister;
1270
+ };
1271
+ const stopAutoSave = () => {
1272
+ ifNotUndefined(autoSaveListenerId, store.delListener);
1273
+ autoSaveListenerId = void 0;
1274
+ return persister;
1275
+ };
1276
+ const isAutoSaving = () => !isUndefined(autoSaveListenerId);
1277
+ const schedule = async (...actions) => {
1278
+ arrayPush(mapGet(scheduleActions, scheduleId), ...actions);
1279
+ await run();
1280
+ return persister;
1281
+ };
1282
+ const getStore = () => store;
1283
+ const destroy = () => stopAutoLoad().stopAutoSave();
1284
+ const getStats = () => ({loads, saves});
1285
+ const persister = {
1286
+ load,
1287
+ startAutoLoad,
1288
+ stopAutoLoad,
1289
+ isAutoLoading,
1290
+ save,
1291
+ startAutoSave,
1292
+ stopAutoSave,
1293
+ isAutoSaving,
1294
+ schedule,
1295
+ getStore,
1296
+ destroy,
1297
+ getStats,
1298
+ ...extra,
1299
+ };
1300
+ return objFreeze(persister);
1301
+ };
1302
+
1303
+ const textEncoder = new globalThis.TextEncoder();
1304
+ const getHash = (value) => {
1305
+ let hash = 2166136261;
1306
+ arrayForEach(textEncoder.encode(value), (char) => {
1307
+ hash ^= char;
1308
+ hash +=
1309
+ (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
1310
+ });
1311
+ return hash >>> 0;
1312
+ };
1313
+
1314
+ const stampCloneWithHash = ([value, time, hash]) => [value, time, hash];
1315
+ const stampCloneWithoutHash = ([value, time]) => newStamp(value, time);
1316
+ const newStamp = (value, time) => (time ? [value, time] : [value]);
1317
+ const getStampHash = (stamp) => stamp[2];
1318
+ const hashIdAndHash = (id, hash) => getHash(id + ':' + hash);
1319
+ const replaceTimeHash = (oldTime, newTime) =>
1320
+ newTime > oldTime ? (oldTime ? getHash(oldTime) : 0) ^ getHash(newTime) : 0;
1321
+ const getLatestTime = (time1, time2) =>
1322
+ ((time1 ?? '') > (time2 ?? '') ? time1 : time2) ?? '';
1323
+ const stampUpdate = (stamp, hash, time) => {
1324
+ stamp[2] = hash >>> 0;
1325
+ if (time > stamp[1]) {
1326
+ stamp[1] = time;
1327
+ }
1328
+ };
1329
+ const stampNewObj = (time = EMPTY_STRING) => newStamp(objNew(), time);
1330
+ const stampNewMap = (time = EMPTY_STRING) => [mapNew(), time, 0];
1331
+ const stampMapToObjWithHash = (
1332
+ [map, time, hash],
1333
+ mapper = stampCloneWithHash,
1334
+ ) => [mapToObj(map, mapper), time, hash];
1335
+ const stampMapToObjWithoutHash = (
1336
+ [map, time],
1337
+ mapper = stampCloneWithoutHash,
1338
+ ) => newStamp(mapToObj(map, mapper), time);
1339
+ const stampValidate = (stamp, validateThing) =>
1340
+ isArray(stamp) &&
1341
+ size(stamp) == 3 &&
1342
+ isString(stamp[1]) &&
1343
+ getTypeOf(stamp[2]) == NUMBER &&
1344
+ isFiniteNumber(stamp[2]) &&
1345
+ validateThing(stamp[0]);
1346
+
1347
+ const MASK6 = 63;
1348
+ const SHIFT36 = 2 ** 36;
1349
+ const SHIFT30 = 2 ** 30;
1350
+ const SHIFT24 = 2 ** 24;
1351
+ const SHIFT18 = 2 ** 18;
1352
+ const SHIFT12 = 2 ** 12;
1353
+ const SHIFT6 = 2 ** 6;
1354
+ const toB64 = (num) => String.fromCharCode(48 + (num & MASK6));
1355
+ const fromB64 = (str, pos) => strCharCodeAt(str, pos) - 48;
1356
+ const encodeHlc = (logicalTime42, counter24, clientHash30) =>
1357
+ toB64(logicalTime42 / SHIFT36) +
1358
+ toB64(logicalTime42 / SHIFT30) +
1359
+ toB64(logicalTime42 / SHIFT24) +
1360
+ toB64(logicalTime42 / SHIFT18) +
1361
+ toB64(logicalTime42 / SHIFT12) +
1362
+ toB64(logicalTime42 / SHIFT6) +
1363
+ toB64(logicalTime42) +
1364
+ toB64(counter24 / SHIFT18) +
1365
+ toB64(counter24 / SHIFT12) +
1366
+ toB64(counter24 / SHIFT6) +
1367
+ toB64(counter24) +
1368
+ toB64(clientHash30 / SHIFT24) +
1369
+ toB64(clientHash30 / SHIFT18) +
1370
+ toB64(clientHash30 / SHIFT12) +
1371
+ toB64(clientHash30 / SHIFT6) +
1372
+ toB64(clientHash30);
1373
+ const decodeHlc = (hlc16) => [
1374
+ fromB64(hlc16, 0) * SHIFT36 +
1375
+ fromB64(hlc16, 1) * SHIFT30 +
1376
+ fromB64(hlc16, 2) * SHIFT24 +
1377
+ fromB64(hlc16, 3) * SHIFT18 +
1378
+ fromB64(hlc16, 4) * SHIFT12 +
1379
+ fromB64(hlc16, 5) * SHIFT6 +
1380
+ fromB64(hlc16, 6),
1381
+ fromB64(hlc16, 7) * SHIFT18 +
1382
+ fromB64(hlc16, 8) * SHIFT12 +
1383
+ fromB64(hlc16, 9) * SHIFT6 +
1384
+ fromB64(hlc16, 10),
1385
+ fromB64(hlc16, 11) * SHIFT24 +
1386
+ fromB64(hlc16, 12) * SHIFT18 +
1387
+ fromB64(hlc16, 13) * SHIFT12 +
1388
+ fromB64(hlc16, 14) * SHIFT6 +
1389
+ fromB64(hlc16, 15),
1390
+ ];
1391
+ const getHlcFunctions = (uniqueId) => {
1392
+ let logicalTime = 0;
1393
+ let lastCounter = -1;
1394
+ const uniqueIdHash = getHash(uniqueId);
1395
+ const getHlc = () => {
1396
+ seenHlc();
1397
+ return encodeHlc(logicalTime, ++lastCounter, uniqueIdHash);
1398
+ };
1399
+ const seenHlc = (hlc) => {
1400
+ const previousLogicalTime = logicalTime;
1401
+ const [remoteLogicalTime, remoteCounter] =
1402
+ isUndefined(hlc) || hlc == '' ? [0, 0] : decodeHlc(hlc);
1403
+ logicalTime = mathMax(
1404
+ previousLogicalTime,
1405
+ remoteLogicalTime,
1406
+ globalThis.HLC_TIME ?? Date.now(),
1407
+ );
1408
+ lastCounter =
1409
+ logicalTime == previousLogicalTime
1410
+ ? logicalTime == remoteLogicalTime
1411
+ ? mathMax(lastCounter, remoteCounter)
1412
+ : lastCounter
1413
+ : logicalTime == remoteLogicalTime
1414
+ ? remoteCounter
1415
+ : -1;
1416
+ };
1417
+ return [getHlc, seenHlc];
1418
+ };
1419
+
1420
+ const RESPONSE = 0;
1421
+ const GET_CONTENT_HASHES = 1;
1422
+ const CONTENT_HASHES = 2;
1423
+ const CONTENT_DIFF = 3;
1424
+ const GET_TABLE_DIFF = 4;
1425
+ const GET_ROW_DIFF = 5;
1426
+ const GET_CELL_DIFF = 6;
1427
+ const GET_VALUE_DIFF = 7;
1428
+ const createCustomSynchronizer = (
1429
+ store,
1430
+ send,
1431
+ onReceive,
1432
+ destroyImpl,
1433
+ requestTimeoutSeconds,
1434
+ onIgnoredError,
1435
+ extra = {},
1436
+ ) => {
1437
+ let persisterListener;
1438
+ let sends = 0;
1439
+ let receives = 0;
1440
+ const [getHlc] = getHlcFunctions(store.getId());
1441
+ const pendingRequests = mapNew();
1442
+ onReceive((fromClientId, requestId, messageType, messageBody) => {
1443
+ {
1444
+ receives++;
1445
+ }
1446
+ if (messageType == RESPONSE) {
1447
+ ifNotUndefined(
1448
+ mapGet(pendingRequests, requestId),
1449
+ ([toClientId, handleResponse]) =>
1450
+ isUndefined(toClientId) || toClientId == fromClientId
1451
+ ? handleResponse(messageBody, fromClientId)
1452
+ : /* istanbul ignore next */
1453
+ 0,
1454
+ );
1455
+ } else if (messageType == CONTENT_HASHES && persister.isAutoLoading()) {
1456
+ getChangesFromOtherStore(fromClientId, messageBody).then((changes) => {
1457
+ persisterListener?.(void 0, changes);
1458
+ });
1459
+ } else if (messageType == CONTENT_DIFF && persister.isAutoLoading()) {
1460
+ persisterListener?.(void 0, messageBody);
1461
+ } else {
1462
+ ifNotUndefined(
1463
+ messageType == GET_CONTENT_HASHES && persister.isAutoSaving()
1464
+ ? store.getMergeableContentHashes()
1465
+ : messageType == GET_TABLE_DIFF
1466
+ ? store.getMergeableTableDiff(messageBody)
1467
+ : messageType == GET_ROW_DIFF
1468
+ ? store.getMergeableRowDiff(messageBody)
1469
+ : messageType == GET_CELL_DIFF
1470
+ ? store.getMergeableCellDiff(messageBody)
1471
+ : messageType == GET_VALUE_DIFF
1472
+ ? store.getMergeableValueDiff(messageBody)
1473
+ : void 0,
1474
+ (response) => {
1475
+ {
1476
+ sends++;
1160
1477
  }
1478
+ send(fromClientId, requestId, RESPONSE, response);
1161
1479
  },
1162
1480
  );
1163
- return persister;
1164
- },
1165
- stopAutoLoad: () => {
1166
- if (listening) {
1167
- delPersisterListener(listeningHandle);
1168
- listeningHandle = void 0;
1169
- listening = 0;
1481
+ }
1482
+ });
1483
+ const request = async (toClientId, messageType, messageBody = EMPTY_STRING) =>
1484
+ promiseNew((resolve, reject) => {
1485
+ const requestId = getHlc();
1486
+ const timeout = setTimeout(() => {
1487
+ collDel(pendingRequests, requestId);
1488
+ reject(
1489
+ `No response from ${toClientId ?? 'anyone'} to '${messageType}'`,
1490
+ );
1491
+ }, requestTimeoutSeconds * 1e3);
1492
+ mapSet(pendingRequests, requestId, [
1493
+ toClientId,
1494
+ (response, fromClientId) => {
1495
+ clearTimeout(timeout);
1496
+ collDel(pendingRequests, requestId);
1497
+ resolve([response, fromClientId]);
1498
+ },
1499
+ ]);
1500
+ {
1501
+ sends++;
1170
1502
  }
1171
- return persister;
1172
- },
1173
- save: async (getTransactionChanges) => {
1174
- /* istanbul ignore else */
1175
- if (loadSave != 1) {
1176
- loadSave = 2;
1177
- {
1178
- saves++;
1503
+ send(toClientId, requestId, messageType, messageBody);
1504
+ });
1505
+ const mergeTablesStamps = (tablesStamp, [tableStamps2, tablesTime2]) => {
1506
+ objForEach(tableStamps2, ([rowStamps2, tableTime2], tableId) => {
1507
+ const tableStamp = objEnsure(tablesStamp[0], tableId, stampNewObj);
1508
+ objForEach(rowStamps2, ([cellStamps2, rowTime2], rowId) => {
1509
+ const rowStamp = objEnsure(tableStamp[0], rowId, stampNewObj);
1510
+ objForEach(
1511
+ cellStamps2,
1512
+ ([cell2, cellTime2], cellId) =>
1513
+ (rowStamp[0][cellId] = newStamp(cell2, cellTime2)),
1514
+ );
1515
+ rowStamp[1] = getLatestTime(rowStamp[1], rowTime2);
1516
+ });
1517
+ tableStamp[1] = getLatestTime(tableStamp[1], tableTime2);
1518
+ });
1519
+ tablesStamp[1] = getLatestTime(tablesStamp[1], tablesTime2);
1520
+ };
1521
+ const getChangesFromOtherStore = async (
1522
+ otherClientId = null,
1523
+ otherContentHashes,
1524
+ ) => {
1525
+ if (isUndefined(otherContentHashes)) {
1526
+ [otherContentHashes, otherClientId] = await request(
1527
+ otherClientId,
1528
+ GET_CONTENT_HASHES,
1529
+ );
1530
+ }
1531
+ const [otherTablesHash, otherValuesHash] = otherContentHashes;
1532
+ const [tablesHash, valuesHash] = store.getMergeableContentHashes();
1533
+ let tablesChanges = stampNewObj();
1534
+ if (tablesHash != otherTablesHash) {
1535
+ const [newTables, differentTableHashes] = (
1536
+ await request(
1537
+ otherClientId,
1538
+ GET_TABLE_DIFF,
1539
+ store.getMergeableTableHashes(),
1540
+ )
1541
+ )[0];
1542
+ tablesChanges = newTables;
1543
+ if (!objIsEmpty(differentTableHashes)) {
1544
+ const [newRows, differentRowHashes] = (
1545
+ await request(
1546
+ otherClientId,
1547
+ GET_ROW_DIFF,
1548
+ store.getMergeableRowHashes(differentTableHashes),
1549
+ )
1550
+ )[0];
1551
+ mergeTablesStamps(tablesChanges, newRows);
1552
+ if (!objIsEmpty(differentRowHashes)) {
1553
+ const newCells = (
1554
+ await request(
1555
+ otherClientId,
1556
+ GET_CELL_DIFF,
1557
+ store.getMergeableCellHashes(differentRowHashes),
1558
+ )
1559
+ )[0];
1560
+ mergeTablesStamps(tablesChanges, newCells);
1179
1561
  }
1180
- await persister.schedule(async () => {
1181
- try {
1182
- await setPersisted(store.getContent, getTransactionChanges);
1183
- } catch (error) {
1184
- /* istanbul ignore next */
1185
- onIgnoredError?.(error);
1186
- }
1187
- loadSave = 0;
1188
- });
1189
1562
  }
1190
- return persister;
1191
- },
1192
- startAutoSave: async () => {
1193
- 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
- );
1202
- return persister;
1203
- },
1204
- stopAutoSave: () => {
1205
- ifNotUndefined(listenerId, store.delListener);
1206
- listenerId = void 0;
1207
- return persister;
1208
- },
1209
- schedule: async (...actions) => {
1210
- arrayPush(mapGet(scheduleActions, scheduleId), ...actions);
1211
- await run();
1212
- return persister;
1213
- },
1214
- getStore: () => store,
1215
- destroy: () => persister.stopAutoLoad().stopAutoSave(),
1216
- getStats: () => ({loads, saves}),
1563
+ }
1564
+ return [
1565
+ tablesChanges,
1566
+ valuesHash == otherValuesHash
1567
+ ? stampNewObj()
1568
+ : (
1569
+ await request(
1570
+ otherClientId,
1571
+ GET_VALUE_DIFF,
1572
+ store.getMergeableValuesHashes(),
1573
+ )
1574
+ )[0],
1575
+ 1,
1576
+ ];
1217
1577
  };
1218
- if (getThing) {
1219
- persister[getThing] = () => thing;
1220
- }
1221
- return objFreeze(persister);
1578
+ const getPersisted = async () => {
1579
+ const changes = await getChangesFromOtherStore();
1580
+ return !objIsEmpty(changes[0][0]) || !objIsEmpty(changes[1][0])
1581
+ ? changes
1582
+ : void 0;
1583
+ };
1584
+ const setPersisted = async (_getContent, changes) => {
1585
+ {
1586
+ sends++;
1587
+ }
1588
+ if (changes) {
1589
+ send(null, null, CONTENT_DIFF, changes);
1590
+ } else {
1591
+ send(null, null, CONTENT_HASHES, store.getMergeableContentHashes());
1592
+ }
1593
+ };
1594
+ const addPersisterListener = (listener) => (persisterListener = listener);
1595
+ const delPersisterListener = () => (persisterListener = void 0);
1596
+ const startSync = async (initialContent) =>
1597
+ await (await persister.startAutoLoad(initialContent)).startAutoSave();
1598
+ const stopSync = () => persister.stopAutoLoad().stopAutoSave();
1599
+ const destroy = () => {
1600
+ destroyImpl();
1601
+ return persister.stopSync();
1602
+ };
1603
+ const getSynchronizerStats = () => ({sends, receives});
1604
+ const persister = createCustomPersister(
1605
+ store,
1606
+ getPersisted,
1607
+ setPersisted,
1608
+ addPersisterListener,
1609
+ delPersisterListener,
1610
+ onIgnoredError,
1611
+ 2,
1612
+ {startSync, stopSync, destroy, getSynchronizerStats, ...extra},
1613
+ );
1614
+ return persister;
1222
1615
  };
1223
1616
 
1224
1617
  const createQueries = getCreateFunction((store) => {
@@ -1648,7 +2041,7 @@ const createQueries = getCreateFunction((store) => {
1648
2041
  destroy,
1649
2042
  getListenerStats,
1650
2043
  };
1651
- objMap(
2044
+ objToArray(
1652
2045
  {
1653
2046
  [TABLE]: [1, 1],
1654
2047
  [TABLE + CELL_IDS]: [0, 1],
@@ -1875,24 +2268,12 @@ const pairNewMap = () => [mapNew(), mapNew()];
1875
2268
  const pairClone = (array) => [...array];
1876
2269
  const pairIsEqual = ([entry1, entry2]) => entry1 === entry2;
1877
2270
 
1878
- const jsonString = (obj) =>
2271
+ const jsonStringWithMap = (obj) =>
1879
2272
  JSON.stringify(obj, (_key, value) =>
1880
2273
  isInstanceOf(value, Map) ? object.fromEntries([...value]) : value,
1881
2274
  );
1882
2275
  const jsonParse = JSON.parse;
1883
2276
 
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
2277
  const idsChanged = (changedIds, id2, addedOrRemoved) =>
1897
2278
  mapSet(
1898
2279
  changedIds,
@@ -1902,11 +2283,10 @@ const idsChanged = (changedIds, id2, addedOrRemoved) =>
1902
2283
  const createStore = () => {
1903
2284
  let hasTablesSchema;
1904
2285
  let hasValuesSchema;
1905
- let cellsTouched = false;
1906
- let valuesTouched = false;
1907
2286
  let hadTables = false;
1908
2287
  let hadValues = false;
1909
2288
  let transactions = 0;
2289
+ let internalListeners = [];
1910
2290
  const changedTableIds = mapNew();
1911
2291
  const changedTableCellIds = mapNew();
1912
2292
  const changedRowCount = mapNew();
@@ -1953,13 +2333,13 @@ const createStore = () => {
1953
2333
  const [addListener, callListeners, delListenerImpl, callListenerImpl] =
1954
2334
  getListenerFunctions(() => store);
1955
2335
  const validateTablesSchema = (tableSchema) =>
1956
- validate(tableSchema, (tableSchema2) =>
1957
- validate(tableSchema2, validateCellOrValueSchema),
2336
+ objValidate(tableSchema, (tableSchema2) =>
2337
+ objValidate(tableSchema2, validateCellOrValueSchema),
1958
2338
  );
1959
2339
  const validateValuesSchema = (valuesSchema) =>
1960
- validate(valuesSchema, validateCellOrValueSchema);
2340
+ objValidate(valuesSchema, validateCellOrValueSchema);
1961
2341
  const validateCellOrValueSchema = (schema) => {
1962
- if (!validate(schema, (_child, id2) => arrayHas([TYPE, DEFAULT], id2))) {
2342
+ if (!objValidate(schema, (_child, id2) => arrayHas([TYPE, DEFAULT], id2))) {
1963
2343
  return false;
1964
2344
  }
1965
2345
  const type = schema[TYPE];
@@ -1972,18 +2352,18 @@ const createStore = () => {
1972
2352
  return true;
1973
2353
  };
1974
2354
  const validateTables = (tables) =>
1975
- validate(tables, validateTable, cellInvalid);
2355
+ objValidate(tables, validateTable, cellInvalid);
1976
2356
  const validateTable = (table, tableId) =>
1977
2357
  (!hasTablesSchema ||
1978
2358
  collHas(tablesSchemaMap, tableId) ||
1979
2359
  cellInvalid(tableId)) &&
1980
- validate(
2360
+ objValidate(
1981
2361
  table,
1982
2362
  (row, rowId) => validateRow(tableId, rowId, row),
1983
2363
  () => cellInvalid(tableId),
1984
2364
  );
1985
2365
  const validateRow = (tableId, rowId, row, skipDefaults) =>
1986
- validate(
2366
+ objValidate(
1987
2367
  skipDefaults ? row : addDefaultsToRow(row, tableId, rowId),
1988
2368
  (cell, cellId) =>
1989
2369
  ifNotUndefined(
@@ -2010,7 +2390,7 @@ const createStore = () => {
2010
2390
  ? cellInvalid(tableId, rowId, cellId, cell)
2011
2391
  : cell;
2012
2392
  const validateValues = (values, skipDefaults) =>
2013
- validate(
2393
+ objValidate(
2014
2394
  skipDefaults ? values : addDefaultsToValues(values),
2015
2395
  (value, valueId) =>
2016
2396
  ifNotUndefined(
@@ -2273,16 +2653,20 @@ const createStore = () => {
2273
2653
  addedOrRemoved,
2274
2654
  );
2275
2655
  };
2276
- const cellChanged = (tableId, rowId, cellId, oldCell, newCell) =>
2277
- (mapEnsure(
2656
+ const cellChanged = (tableId, rowId, cellId, oldCell, newCell) => {
2657
+ mapEnsure(
2278
2658
  mapEnsure(mapEnsure(changedCells, tableId, mapNew), rowId, mapNew),
2279
2659
  cellId,
2280
2660
  () => [oldCell, 0],
2281
- )[1] = newCell);
2661
+ )[1] = newCell;
2662
+ internalListeners[3]?.(tableId, rowId, cellId, newCell);
2663
+ };
2282
2664
  const valueIdsChanged = (valueId, addedOrRemoved) =>
2283
2665
  idsChanged(changedValueIds, valueId, addedOrRemoved);
2284
- const valueChanged = (valueId, oldValue, newValue) =>
2285
- (mapEnsure(changedValues, valueId, () => [oldValue, 0])[1] = newValue);
2666
+ const valueChanged = (valueId, oldValue, newValue) => {
2667
+ mapEnsure(changedValues, valueId, () => [oldValue, 0])[1] = newValue;
2668
+ internalListeners[4]?.(valueId, newValue);
2669
+ };
2286
2670
  const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
2287
2671
  arrayPush(
2288
2672
  mapEnsure(
@@ -2548,44 +2932,6 @@ const createStore = () => {
2548
2932
  transaction(() => actions(...arrayMap(args, id)));
2549
2933
  return store;
2550
2934
  };
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
2935
  const getContent = () => [getTables(), getValues()];
2590
2936
  const getTables = () => mapToObj3(tablesMap);
2591
2937
  const getTableIds = () => mapKeys(tablesMap);
@@ -2629,12 +2975,13 @@ const createStore = () => {
2629
2975
  collHas(mapGet(mapGet(tablesMap, id(tableId)), id(rowId)), id(cellId));
2630
2976
  const hasValues = () => !collIsEmpty(valuesMap);
2631
2977
  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]);
2978
+ const getTablesJson = () => jsonStringWithMap(tablesMap);
2979
+ const getValuesJson = () => jsonStringWithMap(valuesMap);
2980
+ const getJson = () => jsonStringWithMap([tablesMap, valuesMap]);
2981
+ const getTablesSchemaJson = () => jsonStringWithMap(tablesSchemaMap);
2982
+ const getValuesSchemaJson = () => jsonStringWithMap(valuesSchemaMap);
2983
+ const getSchemaJson = () =>
2984
+ jsonStringWithMap([tablesSchemaMap, valuesSchemaMap]);
2638
2985
  const setContent = ([tables, values]) =>
2639
2986
  fluentTransaction(() => {
2640
2987
  (objIsEmpty(tables) ? delTables : setTables)(tables);
@@ -2678,7 +3025,7 @@ const createStore = () => {
2678
3025
  (tableId2, rowId2) => {
2679
3026
  if (validateRow(tableId2, rowId2, partialRow, 1)) {
2680
3027
  const table = getOrCreateTable(tableId2);
2681
- objMap(partialRow, (cell, cellId) =>
3028
+ objToArray(partialRow, (cell, cellId) =>
2682
3029
  setCellIntoDefaultRow(tableId2, table, rowId2, cellId, cell),
2683
3030
  );
2684
3031
  }
@@ -2716,7 +3063,7 @@ const createStore = () => {
2716
3063
  const setPartialValues = (partialValues) =>
2717
3064
  fluentTransaction(() =>
2718
3065
  validateValues(partialValues, 1)
2719
- ? objMap(partialValues, (value, valueId) =>
3066
+ ? objToArray(partialValues, (value, valueId) =>
2720
3067
  setValidValue(valueId, value),
2721
3068
  )
2722
3069
  : 0,
@@ -2733,20 +3080,20 @@ const createStore = () => {
2733
3080
  ),
2734
3081
  valueId,
2735
3082
  );
2736
- const setTransactionChanges = (transactionChanges) =>
3083
+ const applyChanges = (changes) =>
2737
3084
  fluentTransaction(() => {
2738
- objMap(transactionChanges[0], (table, tableId) =>
3085
+ objToArray(changes[0], (table, tableId) =>
2739
3086
  isUndefined(table)
2740
3087
  ? delTable(tableId)
2741
- : objMap(table, (row, rowId) =>
3088
+ : objToArray(table, (row, rowId) =>
2742
3089
  isUndefined(row)
2743
3090
  ? delRow(tableId, rowId)
2744
- : objMap(row, (cell, cellId) =>
3091
+ : objToArray(row, (cell, cellId) =>
2745
3092
  setOrDelCell(store, tableId, rowId, cellId, cell),
2746
3093
  ),
2747
3094
  ),
2748
3095
  );
2749
- objMap(transactionChanges[1], (value, valueId) =>
3096
+ objToArray(changes[1], (value, valueId) =>
2750
3097
  setOrDelValue(store, valueId, value),
2751
3098
  );
2752
3099
  });
@@ -2873,31 +3220,66 @@ const createStore = () => {
2873
3220
  transactions++;
2874
3221
  }
2875
3222
  if (transactions == 1) {
2876
- callListeners(
2877
- startTransactionListeners,
2878
- void 0,
2879
- getTransactionChanges,
2880
- getTransactionLog,
2881
- );
3223
+ internalListeners[0]?.();
3224
+ callListeners(startTransactionListeners);
2882
3225
  }
2883
3226
  return store;
2884
3227
  };
3228
+ const getTransactionChanges = () => [
3229
+ mapToObj(
3230
+ changedCells,
3231
+ (table, tableId) =>
3232
+ mapGet(changedTableIds, tableId) === -1
3233
+ ? void 0
3234
+ : mapToObj(
3235
+ table,
3236
+ (row, rowId) =>
3237
+ mapGet(mapGet(changedRowIds, tableId), rowId) === -1
3238
+ ? void 0
3239
+ : mapToObj(
3240
+ row,
3241
+ ([, newCell]) => newCell,
3242
+ (changedCell) => pairIsEqual(changedCell),
3243
+ ),
3244
+ collIsEmpty,
3245
+ objIsEmpty,
3246
+ ),
3247
+ collIsEmpty,
3248
+ objIsEmpty,
3249
+ ),
3250
+ mapToObj(
3251
+ changedValues,
3252
+ ([, newValue]) => newValue,
3253
+ (changedValue) => pairIsEqual(changedValue),
3254
+ ),
3255
+ 1,
3256
+ ];
3257
+ const getTransactionLog = () => [
3258
+ !collIsEmpty(changedCells),
3259
+ !collIsEmpty(changedValues),
3260
+ mapToObj3(changedCells, pairClone, pairIsEqual),
3261
+ mapToObj3(invalidCells),
3262
+ mapToObj(changedValues, pairClone, pairIsEqual),
3263
+ mapToObj(invalidValues),
3264
+ mapToObj(changedTableIds),
3265
+ mapToObj2(changedRowIds),
3266
+ mapToObj3(changedCellIds),
3267
+ mapToObj(changedValueIds),
3268
+ ];
2885
3269
  const finishTransaction = (doRollback) => {
2886
3270
  if (transactions > 0) {
2887
3271
  transactions--;
2888
3272
  if (transactions == 0) {
2889
- cellsTouched = !collIsEmpty(changedCells);
2890
- valuesTouched = !collIsEmpty(changedValues);
2891
3273
  transactions = 1;
2892
3274
  callInvalidCellListeners(1);
2893
- if (cellsTouched) {
3275
+ if (!collIsEmpty(changedCells)) {
2894
3276
  callTabularListenersForChanges(1);
2895
3277
  }
2896
3278
  callInvalidValueListeners(1);
2897
- if (valuesTouched) {
3279
+ if (!collIsEmpty(changedValues)) {
2898
3280
  callValuesListenersForChanges(1);
2899
3281
  }
2900
- if (doRollback?.(getTransactionChanges, getTransactionLog)) {
3282
+ if (doRollback?.(store)) {
2901
3283
  collForEach(changedCells, (table, tableId) =>
2902
3284
  collForEach(table, (row, rowId) =>
2903
3285
  collForEach(row, ([oldCell], cellId) =>
@@ -2905,34 +3287,26 @@ const createStore = () => {
2905
3287
  ),
2906
3288
  ),
2907
3289
  );
3290
+ collClear(changedCells);
2908
3291
  collForEach(changedValues, ([oldValue], valueId) =>
2909
3292
  setOrDelValue(store, valueId, oldValue),
2910
3293
  );
2911
- cellsTouched = valuesTouched = false;
3294
+ collClear(changedValues);
2912
3295
  }
2913
- callListeners(
2914
- finishTransactionListeners[0],
2915
- void 0,
2916
- getTransactionChanges,
2917
- getTransactionLog,
2918
- );
3296
+ callListeners(finishTransactionListeners[0], void 0);
2919
3297
  transactions = -1;
2920
3298
  callInvalidCellListeners(0);
2921
- if (cellsTouched) {
3299
+ if (!collIsEmpty(changedCells)) {
2922
3300
  callTabularListenersForChanges(0);
2923
3301
  }
2924
3302
  callInvalidValueListeners(0);
2925
- if (valuesTouched) {
3303
+ if (!collIsEmpty(changedValues)) {
2926
3304
  callValuesListenersForChanges(0);
2927
3305
  }
2928
- callListeners(
2929
- finishTransactionListeners[1],
2930
- void 0,
2931
- getTransactionChanges,
2932
- getTransactionLog,
2933
- );
3306
+ internalListeners[1]?.();
3307
+ callListeners(finishTransactionListeners[1], void 0);
3308
+ internalListeners[2]?.();
2934
3309
  transactions = 0;
2935
- cellsTouched = valuesTouched = false;
2936
3310
  hadTables = hasTables();
2937
3311
  hadValues = hasValues();
2938
3312
  arrayForEach(
@@ -3057,6 +3431,20 @@ const createStore = () => {
3057
3431
  collSize2(startTransactionListeners) +
3058
3432
  pairCollSize2(finishTransactionListeners),
3059
3433
  });
3434
+ const setInternalListeners = (
3435
+ preStartTransaction,
3436
+ preFinishTransaction,
3437
+ postFinishTransaction,
3438
+ cellChanged2,
3439
+ valueChanged2,
3440
+ ) =>
3441
+ (internalListeners = [
3442
+ preStartTransaction,
3443
+ preFinishTransaction,
3444
+ postFinishTransaction,
3445
+ cellChanged2,
3446
+ valueChanged2,
3447
+ ]);
3060
3448
  const store = {
3061
3449
  getContent,
3062
3450
  getTables,
@@ -3097,7 +3485,7 @@ const createStore = () => {
3097
3485
  setValues,
3098
3486
  setPartialValues,
3099
3487
  setValue,
3100
- setTransactionChanges,
3488
+ applyChanges,
3101
3489
  setTablesJson,
3102
3490
  setValuesJson,
3103
3491
  setJson,
@@ -3115,6 +3503,8 @@ const createStore = () => {
3115
3503
  delSchema,
3116
3504
  transaction,
3117
3505
  startTransaction,
3506
+ getTransactionChanges,
3507
+ getTransactionLog,
3118
3508
  finishTransaction,
3119
3509
  forEachTable,
3120
3510
  forEachTableCell,
@@ -3132,8 +3522,9 @@ const createStore = () => {
3132
3522
  createStore,
3133
3523
  addListener,
3134
3524
  callListeners,
3525
+ setInternalListeners,
3135
3526
  };
3136
- objMap(
3527
+ objToArray(
3137
3528
  {
3138
3529
  [HAS + TABLES]: [0, hasTablesListeners, [], () => [hasTables()]],
3139
3530
  [TABLES]: [0, tablesListeners],
@@ -3206,10 +3597,484 @@ const createStore = () => {
3206
3597
  return objFreeze(store);
3207
3598
  };
3208
3599
 
3600
+ const LISTENER_ARGS = {
3601
+ HasTable: 1,
3602
+ Table: 1,
3603
+ TableCellIds: 1,
3604
+ HasTableCell: 2,
3605
+ RowCount: 1,
3606
+ RowIds: 1,
3607
+ SortedRowIds: 5,
3608
+ HasRow: 2,
3609
+ Row: 2,
3610
+ CellIds: 2,
3611
+ HasCell: 3,
3612
+ Cell: 3,
3613
+ HasValue: 1,
3614
+ Value: 1,
3615
+ InvalidCell: 3,
3616
+ InvalidValue: 1,
3617
+ };
3618
+ const newContentStampMap = (time = EMPTY_STRING) => [
3619
+ stampNewMap(time),
3620
+ stampNewMap(time),
3621
+ ];
3622
+ const validateMergeableContent = (mergeableContent) =>
3623
+ isArray(mergeableContent) &&
3624
+ size(mergeableContent) == 2 &&
3625
+ stampValidate(mergeableContent[0], (tableStamps) =>
3626
+ objValidate(
3627
+ tableStamps,
3628
+ (tableStamp) =>
3629
+ stampValidate(tableStamp, (rowStamps) =>
3630
+ objValidate(
3631
+ rowStamps,
3632
+ (rowStamp) =>
3633
+ stampValidate(rowStamp, (cellStamps) =>
3634
+ objValidate(
3635
+ cellStamps,
3636
+ (cellStamp) =>
3637
+ stampValidate(cellStamp, isCellOrValueOrNullOrUndefined),
3638
+ void 0,
3639
+ 1,
3640
+ ),
3641
+ ),
3642
+ void 0,
3643
+ 1,
3644
+ ),
3645
+ ),
3646
+ void 0,
3647
+ 1,
3648
+ ),
3649
+ ) &&
3650
+ stampValidate(mergeableContent[1], (values) =>
3651
+ objValidate(
3652
+ values,
3653
+ (value) => stampValidate(value, isCellOrValueOrNullOrUndefined),
3654
+ void 0,
3655
+ 1,
3656
+ ),
3657
+ );
3658
+ const createMergeableStore = (id) => {
3659
+ let listeningToRawStoreChanges = 1;
3660
+ let contentStampMap = newContentStampMap();
3661
+ let defaultingContent = 0;
3662
+ const touchedCells = mapNew();
3663
+ const touchedValues = setNew();
3664
+ const [getHlc, seenHlc] = getHlcFunctions(id);
3665
+ const store = createStore();
3666
+ const disableListeningToRawStoreChanges = (actions) => {
3667
+ const wasListening = listeningToRawStoreChanges;
3668
+ listeningToRawStoreChanges = 0;
3669
+ actions();
3670
+ listeningToRawStoreChanges = wasListening;
3671
+ return mergeableStore;
3672
+ };
3673
+ const mergeContentOrChanges = (contentOrChanges, isContent = 0) => {
3674
+ const tablesChanges = {};
3675
+ const valuesChanges = {};
3676
+ const [
3677
+ [tablesObj, incomingTablesTime = EMPTY_STRING, incomingTablesHash = 0],
3678
+ values,
3679
+ ] = contentOrChanges;
3680
+ const [tablesStampMap, valuesStampMap] = contentStampMap;
3681
+ const [tableStampMaps, oldTablesTime, oldTablesHash] = tablesStampMap;
3682
+ let tablesHash = isContent ? incomingTablesHash : oldTablesHash;
3683
+ let tablesTime = incomingTablesTime;
3684
+ objForEach(
3685
+ tablesObj,
3686
+ (
3687
+ [rowsObj, incomingTableTime = EMPTY_STRING, incomingTableHash = 0],
3688
+ tableId,
3689
+ ) => {
3690
+ const tableStampMap = mapEnsure(tableStampMaps, tableId, stampNewMap);
3691
+ const [rowStampMaps, oldTableTime, oldTableHash] = tableStampMap;
3692
+ let tableHash = isContent ? incomingTableHash : oldTableHash;
3693
+ let tableTime = incomingTableTime;
3694
+ objForEach(rowsObj, (row, rowId) => {
3695
+ const [rowTime, oldRowHash, rowHash] = mergeCellsOrValues(
3696
+ row,
3697
+ mapEnsure(rowStampMaps, rowId, stampNewMap),
3698
+ objEnsure(objEnsure(tablesChanges, tableId, objNew), rowId, objNew),
3699
+ isContent,
3700
+ );
3701
+ tableHash ^= isContent
3702
+ ? 0
3703
+ : (oldRowHash ? hashIdAndHash(rowId, oldRowHash) : 0) ^
3704
+ hashIdAndHash(rowId, rowHash);
3705
+ tableTime = getLatestTime(tableTime, rowTime);
3706
+ });
3707
+ tableHash ^= isContent
3708
+ ? 0
3709
+ : replaceTimeHash(oldTableTime, incomingTableTime);
3710
+ stampUpdate(tableStampMap, tableHash, incomingTableTime);
3711
+ tablesHash ^= isContent
3712
+ ? 0
3713
+ : (oldTableHash ? hashIdAndHash(tableId, oldTableHash) : 0) ^
3714
+ hashIdAndHash(tableId, tableStampMap[2]);
3715
+ tablesTime = getLatestTime(tablesTime, tableTime);
3716
+ },
3717
+ );
3718
+ tablesHash ^= isContent
3719
+ ? 0
3720
+ : replaceTimeHash(oldTablesTime, incomingTablesTime);
3721
+ stampUpdate(tablesStampMap, tablesHash, incomingTablesTime);
3722
+ const [valuesTime] = mergeCellsOrValues(
3723
+ values,
3724
+ valuesStampMap,
3725
+ valuesChanges,
3726
+ isContent,
3727
+ );
3728
+ seenHlc(getLatestTime(tablesTime, valuesTime));
3729
+ return [tablesChanges, valuesChanges, 1];
3730
+ };
3731
+ const mergeCellsOrValues = (
3732
+ things,
3733
+ thingsStampMap,
3734
+ thingsChanges,
3735
+ isContent,
3736
+ ) => {
3737
+ const [
3738
+ thingsObj,
3739
+ incomingThingsTime = EMPTY_STRING,
3740
+ incomingThingsHash = 0,
3741
+ ] = things;
3742
+ const [thingStampMaps, oldThingsTime, oldThingsHash] = thingsStampMap;
3743
+ let thingsTime = incomingThingsTime;
3744
+ let thingsHash = isContent ? incomingThingsHash : oldThingsHash;
3745
+ objForEach(
3746
+ thingsObj,
3747
+ ([thing, thingTime, incomingThingHash = 0], thingId) => {
3748
+ const thingStampMap = mapEnsure(thingStampMaps, thingId, () => [
3749
+ void 0,
3750
+ EMPTY_STRING,
3751
+ 0,
3752
+ ]);
3753
+ const [, oldThingTime, oldThingHash] = thingStampMap;
3754
+ if (!oldThingTime || thingTime > oldThingTime) {
3755
+ stampUpdate(
3756
+ thingStampMap,
3757
+ isContent
3758
+ ? incomingThingHash
3759
+ : getHash(jsonStringWithMap(thing ?? null) + ':' + thingTime),
3760
+ thingTime,
3761
+ );
3762
+ thingStampMap[0] = thing;
3763
+ thingsChanges[thingId] = thing;
3764
+ thingsHash ^= isContent
3765
+ ? 0
3766
+ : hashIdAndHash(thingId, oldThingHash) ^
3767
+ hashIdAndHash(thingId, thingStampMap[2]);
3768
+ thingsTime = getLatestTime(thingsTime, thingTime);
3769
+ }
3770
+ },
3771
+ );
3772
+ thingsHash ^= isContent
3773
+ ? 0
3774
+ : replaceTimeHash(oldThingsTime, incomingThingsTime);
3775
+ stampUpdate(thingsStampMap, thingsHash, incomingThingsTime);
3776
+ return [thingsTime, oldThingsHash, thingsStampMap[2]];
3777
+ };
3778
+ const preStartTransaction = () => {};
3779
+ const preFinishTransaction = () => {};
3780
+ const postFinishTransaction = () => {
3781
+ collClear(touchedCells);
3782
+ collClear(touchedValues);
3783
+ };
3784
+ const cellChanged = (tableId, rowId, cellId, newCell) => {
3785
+ setAdd(
3786
+ mapEnsure(mapEnsure(touchedCells, tableId, mapNew), rowId, setNew),
3787
+ cellId,
3788
+ );
3789
+ if (listeningToRawStoreChanges) {
3790
+ mergeContentOrChanges([
3791
+ [
3792
+ {
3793
+ [tableId]: [
3794
+ {
3795
+ [rowId]: [
3796
+ {
3797
+ [cellId]: [
3798
+ newCell,
3799
+ defaultingContent ? EMPTY_STRING : getHlc(),
3800
+ ],
3801
+ },
3802
+ ],
3803
+ },
3804
+ ],
3805
+ },
3806
+ ],
3807
+ [{}],
3808
+ 1,
3809
+ ]);
3810
+ }
3811
+ };
3812
+ const valueChanged = (valueId, newValue) => {
3813
+ setAdd(touchedValues, valueId);
3814
+ if (listeningToRawStoreChanges) {
3815
+ mergeContentOrChanges([
3816
+ [{}],
3817
+ [{[valueId]: [newValue, defaultingContent ? EMPTY_STRING : getHlc()]}],
3818
+ 1,
3819
+ ]);
3820
+ }
3821
+ };
3822
+ const getId = () => id;
3823
+ const getMergeableContent = () => [
3824
+ stampMapToObjWithHash(contentStampMap[0], (tableStampMap) =>
3825
+ stampMapToObjWithHash(tableStampMap, (rowStampMap) =>
3826
+ stampMapToObjWithHash(rowStampMap),
3827
+ ),
3828
+ ),
3829
+ stampMapToObjWithHash(contentStampMap[1]),
3830
+ ];
3831
+ const getMergeableContentHashes = () => [
3832
+ contentStampMap[0][2],
3833
+ contentStampMap[1][2],
3834
+ ];
3835
+ const getMergeableTableHashes = () =>
3836
+ mapToObj(contentStampMap[0][0], getStampHash);
3837
+ const getMergeableTableDiff = (otherTableHashes) => {
3838
+ const newTables = stampNewObj(contentStampMap[0][1]);
3839
+ const differentTableHashes = {};
3840
+ mapForEach(
3841
+ contentStampMap[0][0],
3842
+ (tableId, [tableStampMap, tableTime, hash]) =>
3843
+ objHas(otherTableHashes, tableId)
3844
+ ? hash != otherTableHashes[tableId]
3845
+ ? (differentTableHashes[tableId] = hash)
3846
+ : 0
3847
+ : (newTables[0][tableId] = stampMapToObjWithoutHash(
3848
+ [tableStampMap, tableTime],
3849
+ (rowStampMap) => stampMapToObjWithoutHash(rowStampMap),
3850
+ )),
3851
+ );
3852
+ return [newTables, differentTableHashes];
3853
+ };
3854
+ const getMergeableRowHashes = (otherTableHashes) => {
3855
+ const rowHashes = {};
3856
+ objForEach(otherTableHashes, (otherTableHash, tableId) =>
3857
+ ifNotUndefined(
3858
+ mapGet(contentStampMap[0][0], tableId),
3859
+ ([rowStampMaps, , tableHash]) =>
3860
+ tableHash != otherTableHash
3861
+ ? mapForEach(
3862
+ rowStampMaps,
3863
+ (rowId, [, , rowHash]) =>
3864
+ (objEnsure(rowHashes, tableId, objNew)[rowId] = rowHash),
3865
+ )
3866
+ : 0,
3867
+ ),
3868
+ );
3869
+ return rowHashes;
3870
+ };
3871
+ const getMergeableRowDiff = (otherTableRowHashes) => {
3872
+ const newRows = stampNewObj(contentStampMap[0][1]);
3873
+ const differentRowHashes = {};
3874
+ objForEach(otherTableRowHashes, (otherRowHashes, tableId) =>
3875
+ mapForEach(
3876
+ mapGet(contentStampMap[0][0], tableId)?.[0],
3877
+ (rowId, [rowStampMap, rowTime, hash]) =>
3878
+ objHas(otherRowHashes, rowId)
3879
+ ? hash !== otherRowHashes[rowId]
3880
+ ? (objEnsure(differentRowHashes, tableId, objNew)[rowId] = hash)
3881
+ : 0
3882
+ : (objEnsure(newRows[0], tableId, stampNewObj)[0][rowId] =
3883
+ stampMapToObjWithoutHash([rowStampMap, rowTime])),
3884
+ ),
3885
+ );
3886
+ return [newRows, differentRowHashes];
3887
+ };
3888
+ const getMergeableCellHashes = (otherTableRowHashes) => {
3889
+ const cellHashes = {};
3890
+ objForEach(otherTableRowHashes, (otherRowHashes, tableId) =>
3891
+ ifNotUndefined(mapGet(contentStampMap[0][0], tableId), ([rowStampMaps]) =>
3892
+ objForEach(otherRowHashes, (otherRowHash, rowId) =>
3893
+ ifNotUndefined(
3894
+ mapGet(rowStampMaps, rowId),
3895
+ ([cellStampMaps, , rowHash]) =>
3896
+ rowHash !== otherRowHash
3897
+ ? mapForEach(
3898
+ cellStampMaps,
3899
+ (cellId, [, , cellHash]) =>
3900
+ (objEnsure(
3901
+ objEnsure(cellHashes, tableId, objNew),
3902
+ rowId,
3903
+ objNew,
3904
+ )[cellId] = cellHash),
3905
+ )
3906
+ : 0,
3907
+ ),
3908
+ ),
3909
+ ),
3910
+ );
3911
+ return cellHashes;
3912
+ };
3913
+ const getMergeableCellDiff = (otherTableRowCellHashes) => {
3914
+ const [[tableStampMaps, tablesTime]] = contentStampMap;
3915
+ const tablesObj = {};
3916
+ objForEach(otherTableRowCellHashes, (otherRowCellHashes, tableId) =>
3917
+ objForEach(otherRowCellHashes, (otherCellHashes, rowId) =>
3918
+ ifNotUndefined(
3919
+ mapGet(tableStampMaps, tableId),
3920
+ ([rowStampMaps, tableTime]) =>
3921
+ ifNotUndefined(
3922
+ mapGet(rowStampMaps, rowId),
3923
+ ([cellStampMaps, rowTime]) =>
3924
+ mapForEach(cellStampMaps, (cellId, [cell, cellTime, hash]) =>
3925
+ hash !== otherCellHashes[cellId]
3926
+ ? (objEnsure(
3927
+ objEnsure(tablesObj, tableId, () =>
3928
+ stampNewObj(tableTime),
3929
+ )[0],
3930
+ rowId,
3931
+ () => stampNewObj(rowTime),
3932
+ )[0][cellId] = [cell, cellTime])
3933
+ : 0,
3934
+ ),
3935
+ ),
3936
+ ),
3937
+ ),
3938
+ );
3939
+ return newStamp(tablesObj, tablesTime);
3940
+ };
3941
+ const getMergeableValuesHashes = () =>
3942
+ mapToObj(contentStampMap[1][0], getStampHash);
3943
+ const getMergeableValueDiff = (relativeTo) => {
3944
+ const [, [valueStampMaps, valuesTime]] = contentStampMap;
3945
+ const values = mapToObj(
3946
+ valueStampMaps,
3947
+ stampCloneWithoutHash,
3948
+ ([, , hash], valueId) => hash == relativeTo?.[valueId],
3949
+ );
3950
+ return newStamp(values, valuesTime);
3951
+ };
3952
+ const setMergeableContent = (mergeableContent) =>
3953
+ disableListeningToRawStoreChanges(() =>
3954
+ validateMergeableContent(mergeableContent)
3955
+ ? store.transaction(() => {
3956
+ store.delTables().delValues();
3957
+ contentStampMap = newContentStampMap();
3958
+ store.applyChanges(mergeContentOrChanges(mergeableContent, 1));
3959
+ })
3960
+ : 0,
3961
+ );
3962
+ const setDefaultContent = (content) => {
3963
+ store.transaction(() => {
3964
+ defaultingContent = 1;
3965
+ store.setContent(content);
3966
+ defaultingContent = 0;
3967
+ });
3968
+ return mergeableStore;
3969
+ };
3970
+ const getTransactionMergeableChanges = () => {
3971
+ const [[tableStampMaps, tablesTime], [valueStampMaps, valuesTime]] =
3972
+ contentStampMap;
3973
+ const tablesObj = {};
3974
+ collForEach(touchedCells, (touchedTable, tableId) =>
3975
+ ifNotUndefined(
3976
+ mapGet(tableStampMaps, tableId),
3977
+ ([rowStampMaps, tableTime]) => {
3978
+ const tableObj = {};
3979
+ collForEach(touchedTable, (touchedRow, rowId) =>
3980
+ ifNotUndefined(
3981
+ mapGet(rowStampMaps, rowId),
3982
+ ([cellStampMaps, rowTime]) => {
3983
+ const rowObj = {};
3984
+ collForEach(touchedRow, (cellId) => {
3985
+ ifNotUndefined(
3986
+ mapGet(cellStampMaps, cellId),
3987
+ ([cell, time]) => (rowObj[cellId] = newStamp(cell, time)),
3988
+ );
3989
+ });
3990
+ tableObj[rowId] = newStamp(rowObj, rowTime);
3991
+ },
3992
+ ),
3993
+ );
3994
+ tablesObj[tableId] = newStamp(tableObj, tableTime);
3995
+ },
3996
+ ),
3997
+ );
3998
+ const valuesObj = {};
3999
+ collForEach(touchedValues, (valueId) =>
4000
+ ifNotUndefined(
4001
+ mapGet(valueStampMaps, valueId),
4002
+ ([value, time]) => (valuesObj[valueId] = newStamp(value, time)),
4003
+ ),
4004
+ );
4005
+ return [
4006
+ newStamp(tablesObj, tablesTime),
4007
+ newStamp(valuesObj, valuesTime),
4008
+ 1,
4009
+ ];
4010
+ };
4011
+ const applyMergeableChanges = (mergeableChanges) =>
4012
+ disableListeningToRawStoreChanges(() =>
4013
+ store.applyChanges(mergeContentOrChanges(mergeableChanges)),
4014
+ );
4015
+ const merge = (mergeableStore2) => {
4016
+ const mergeableChanges = getMergeableContent();
4017
+ const mergeableChanges2 = mergeableStore2.getMergeableContent();
4018
+ mergeableStore2.applyMergeableChanges(mergeableChanges);
4019
+ return applyMergeableChanges(mergeableChanges2);
4020
+ };
4021
+ const mergeableStore = {
4022
+ getId,
4023
+ getMergeableContent,
4024
+ getMergeableContentHashes,
4025
+ getMergeableTableHashes,
4026
+ getMergeableTableDiff,
4027
+ getMergeableRowHashes,
4028
+ getMergeableRowDiff,
4029
+ getMergeableCellHashes,
4030
+ getMergeableCellDiff,
4031
+ getMergeableValuesHashes,
4032
+ getMergeableValueDiff,
4033
+ setMergeableContent,
4034
+ setDefaultContent,
4035
+ getTransactionMergeableChanges,
4036
+ applyMergeableChanges,
4037
+ merge,
4038
+ };
4039
+ store.setInternalListeners(
4040
+ preStartTransaction,
4041
+ preFinishTransaction,
4042
+ postFinishTransaction,
4043
+ cellChanged,
4044
+ valueChanged,
4045
+ );
4046
+ objToArray(
4047
+ store,
4048
+ (method, name) =>
4049
+ (mergeableStore[name] = // fluent methods
4050
+ strStartsWith(name, 'set') ||
4051
+ strStartsWith(name, 'del') ||
4052
+ strStartsWith(name, 'apply') ||
4053
+ strEndsWith(name, 'Transaction') ||
4054
+ name == 'callListener'
4055
+ ? (...args) => {
4056
+ method(...args);
4057
+ return mergeableStore;
4058
+ }
4059
+ : strStartsWith(name, 'add') && strEndsWith(name, 'Listener')
4060
+ ? (...args) => {
4061
+ const listenerArg = LISTENER_ARGS[slice(name, 3, -8)] ?? 0;
4062
+ const listener = args[listenerArg];
4063
+ args[listenerArg] = (_store, ...args2) =>
4064
+ listener(mergeableStore, ...args2);
4065
+ return method(...args);
4066
+ }
4067
+ : method),
4068
+ );
4069
+ return objFreeze(mergeableStore);
4070
+ };
4071
+
3209
4072
  export {
3210
4073
  createCheckpoints,
3211
4074
  createCustomPersister,
4075
+ createCustomSynchronizer,
3212
4076
  createIndexes,
4077
+ createMergeableStore,
3213
4078
  createMetrics,
3214
4079
  createQueries,
3215
4080
  createRelationships,