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
@@ -0,0 +1,2230 @@
1
+ const getTypeOf = (thing) => typeof thing;
2
+ const EMPTY_STRING = '';
3
+ const STRING = getTypeOf(EMPTY_STRING);
4
+ const BOOLEAN = getTypeOf(true);
5
+ const NUMBER = getTypeOf(0);
6
+ const FUNCTION = getTypeOf(getTypeOf);
7
+ const TYPE = 'type';
8
+ const DEFAULT = 'default';
9
+ const LISTENER = 'Listener';
10
+ const ADD = 'add';
11
+ const HAS = 'Has';
12
+ const IDS = 'Ids';
13
+ const TABLE = 'Table';
14
+ const TABLES = TABLE + 's';
15
+ const TABLE_IDS = TABLE + IDS;
16
+ const ROW = 'Row';
17
+ const ROW_COUNT = ROW + 'Count';
18
+ const ROW_IDS = ROW + IDS;
19
+ const CELL = 'Cell';
20
+ const CELL_IDS = CELL + IDS;
21
+ const VALUE = 'Value';
22
+ const VALUES = VALUE + 's';
23
+ const VALUE_IDS = VALUE + IDS;
24
+ const id = (key) => EMPTY_STRING + key;
25
+ const strStartsWith = (str, prefix) => str.startsWith(prefix);
26
+ const strEndsWith = (str, suffix) => str.endsWith(suffix);
27
+ const strCharCodeAt = (str, position) => str.charCodeAt(position);
28
+
29
+ const mathMax = Math.max;
30
+ const isFiniteNumber = isFinite;
31
+ const isInstanceOf = (thing, cls) => thing instanceof cls;
32
+ const isUndefined = (thing) => thing == void 0;
33
+ const ifNotUndefined = (value, then, otherwise) =>
34
+ isUndefined(value) ? otherwise?.() : then(value);
35
+ const isTypeStringOrBoolean = (type) => type == STRING || type == BOOLEAN;
36
+ const isString = (thing) => getTypeOf(thing) == STRING;
37
+ const isFunction = (thing) => getTypeOf(thing) == FUNCTION;
38
+ const isArray = (thing) => Array.isArray(thing);
39
+ const slice = (arrayOrString, start, end) => arrayOrString.slice(start, end);
40
+ const size = (arrayOrString) => arrayOrString.length;
41
+ const test = (regex, subject) => regex.test(subject);
42
+
43
+ const arrayHas = (array, value) => array.includes(value);
44
+ const arrayEvery = (array, cb) => array.every(cb);
45
+ const arrayIsEqual = (array1, array2) =>
46
+ size(array1) === size(array2) &&
47
+ arrayEvery(array1, (value1, index) => array2[index] === value1);
48
+ const arraySort = (array, sorter) => array.sort(sorter);
49
+ const arrayForEach = (array, cb) => array.forEach(cb);
50
+ const arrayMap = (array, cb) => array.map(cb);
51
+ const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
52
+ const arrayPush = (array, ...values) => array.push(...values);
53
+ const arrayShift = (array) => array.shift();
54
+
55
+ const object = Object;
56
+ const getPrototypeOf = (obj) => object.getPrototypeOf(obj);
57
+ const objEntries = object.entries;
58
+ const objFrozen = object.isFrozen;
59
+ const isObject = (obj) =>
60
+ !isUndefined(obj) &&
61
+ ifNotUndefined(
62
+ getPrototypeOf(obj),
63
+ (objPrototype) =>
64
+ objPrototype == object.prototype ||
65
+ isUndefined(getPrototypeOf(objPrototype)),
66
+ /* istanbul ignore next */
67
+ () => true,
68
+ );
69
+ const objIds = object.keys;
70
+ const objFreeze = object.freeze;
71
+ const objNew = (entries = []) => object.fromEntries(entries);
72
+ const objHas = (obj, id) => id in obj;
73
+ const objDel = (obj, id) => {
74
+ delete obj[id];
75
+ return obj;
76
+ };
77
+ const objForEach = (obj, cb) =>
78
+ arrayForEach(objEntries(obj), ([id, value]) => cb(value, id));
79
+ const objToArray = (obj, cb) =>
80
+ arrayMap(objEntries(obj), ([id, value]) => cb(value, id));
81
+ const objSize = (obj) => size(objIds(obj));
82
+ const objIsEmpty = (obj) => isObject(obj) && objSize(obj) == 0;
83
+ const objEnsure = (obj, id, getDefaultValue) => {
84
+ if (!objHas(obj, id)) {
85
+ obj[id] = getDefaultValue();
86
+ }
87
+ return obj[id];
88
+ };
89
+ const objValidate = (obj, validateChild, onInvalidObj, emptyIsValid = 0) => {
90
+ if (
91
+ isUndefined(obj) ||
92
+ !isObject(obj) ||
93
+ (!emptyIsValid && objIsEmpty(obj)) ||
94
+ objFrozen(obj)
95
+ ) {
96
+ onInvalidObj?.();
97
+ return false;
98
+ }
99
+ objToArray(obj, (child, id) => {
100
+ if (!validateChild(child, id)) {
101
+ objDel(obj, id);
102
+ }
103
+ });
104
+ return emptyIsValid ? true : !objIsEmpty(obj);
105
+ };
106
+
107
+ const setNew = (entryOrEntries) =>
108
+ new Set(
109
+ isArray(entryOrEntries) || isUndefined(entryOrEntries)
110
+ ? entryOrEntries
111
+ : [entryOrEntries],
112
+ );
113
+ const setAdd = (set, value) => set?.add(value);
114
+
115
+ const collSizeN = (collSizer) => (coll) =>
116
+ arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
117
+ const collSize = (coll) => coll?.size ?? 0;
118
+ const collSize2 = collSizeN(collSize);
119
+ const collSize3 = collSizeN(collSize2);
120
+ const collSize4 = collSizeN(collSize3);
121
+ const collHas = (coll, keyOrValue) => coll?.has(keyOrValue) ?? false;
122
+ const collIsEmpty = (coll) => isUndefined(coll) || collSize(coll) == 0;
123
+ const collValues = (coll) => [...(coll?.values() ?? [])];
124
+ const collClear = (coll) => coll.clear();
125
+ const collForEach = (coll, cb) => coll?.forEach(cb);
126
+ const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
127
+
128
+ const mapNew = (entries) => new Map(entries);
129
+ const mapKeys = (map) => [...(map?.keys() ?? [])];
130
+ const mapGet = (map, key) => map?.get(key);
131
+ const mapForEach = (map, cb) =>
132
+ collForEach(map, (value, key) => cb(key, value));
133
+ const mapMap = (coll, cb) =>
134
+ arrayMap([...(coll?.entries() ?? [])], ([key, value]) => cb(value, key));
135
+ const mapSet = (map, key, value) =>
136
+ isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
137
+ const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
138
+ if (!collHas(map, key)) {
139
+ mapSet(map, key, getDefaultValue());
140
+ } else {
141
+ hadExistingValue?.(mapGet(map, key));
142
+ }
143
+ return mapGet(map, key);
144
+ };
145
+ const mapMatch = (map, obj, set, del = mapSet) => {
146
+ objToArray(obj, (value, id) => set(map, id, value));
147
+ mapForEach(map, (id) => (objHas(obj, id) ? 0 : del(map, id)));
148
+ return map;
149
+ };
150
+ const mapToObj = (map, valueMapper, excludeMapValue, excludeObjValue) => {
151
+ const obj = {};
152
+ collForEach(map, (mapValue, id) => {
153
+ if (!excludeMapValue?.(mapValue, id)) {
154
+ const objValue = valueMapper ? valueMapper(mapValue, id) : mapValue;
155
+ excludeObjValue?.(objValue) ? 0 : (obj[id] = objValue);
156
+ }
157
+ });
158
+ return obj;
159
+ };
160
+ const mapToObj2 = (map, valueMapper, excludeMapValue) =>
161
+ mapToObj(
162
+ map,
163
+ (childMap) => mapToObj(childMap, valueMapper, excludeMapValue),
164
+ collIsEmpty,
165
+ objIsEmpty,
166
+ );
167
+ const mapToObj3 = (map, valueMapper, excludeMapValue) =>
168
+ mapToObj(
169
+ map,
170
+ (childMap) => mapToObj2(childMap, valueMapper, excludeMapValue),
171
+ collIsEmpty,
172
+ objIsEmpty,
173
+ );
174
+ const mapClone = (map, mapValue) => {
175
+ const map2 = mapNew();
176
+ collForEach(map, (value, key) => map2.set(key, mapValue?.(value) ?? value));
177
+ return map2;
178
+ };
179
+ const mapClone2 = (map) => mapClone(map, mapClone);
180
+ const mapClone3 = (map) => mapClone(map, mapClone2);
181
+ const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
182
+ ifNotUndefined(
183
+ (ensureLeaf ? mapEnsure : mapGet)(
184
+ node,
185
+ path[p],
186
+ p > size(path) - 2 ? ensureLeaf : mapNew,
187
+ ),
188
+ (nodeOrLeaf) => {
189
+ if (p > size(path) - 2) {
190
+ if (pruneLeaf?.(nodeOrLeaf)) {
191
+ mapSet(node, path[p]);
192
+ }
193
+ return nodeOrLeaf;
194
+ }
195
+ const leaf = visitTree(nodeOrLeaf, path, ensureLeaf, pruneLeaf, p + 1);
196
+ if (collIsEmpty(nodeOrLeaf)) {
197
+ mapSet(node, path[p]);
198
+ }
199
+ return leaf;
200
+ },
201
+ );
202
+
203
+ const textEncoder = new globalThis.TextEncoder();
204
+ const getHash = (value) => {
205
+ let hash = 2166136261;
206
+ arrayForEach(textEncoder.encode(value), (char) => {
207
+ hash ^= char;
208
+ hash +=
209
+ (hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
210
+ });
211
+ return hash >>> 0;
212
+ };
213
+
214
+ const stampCloneWithHash = ([value, time, hash]) => [value, time, hash];
215
+ const stampCloneWithoutHash = ([value, time]) => newStamp(value, time);
216
+ const newStamp = (value, time) => (time ? [value, time] : [value]);
217
+ const getStampHash = (stamp) => stamp[2];
218
+ const hashIdAndHash = (id, hash) => getHash(id + ':' + hash);
219
+ const replaceTimeHash = (oldTime, newTime) =>
220
+ newTime > oldTime ? (oldTime ? getHash(oldTime) : 0) ^ getHash(newTime) : 0;
221
+ const getLatestTime = (time1, time2) =>
222
+ ((time1 ?? '') > (time2 ?? '') ? time1 : time2) ?? '';
223
+ const stampUpdate = (stamp, hash, time) => {
224
+ stamp[2] = hash >>> 0;
225
+ if (time > stamp[1]) {
226
+ stamp[1] = time;
227
+ }
228
+ };
229
+ const stampNewObj = (time = EMPTY_STRING) => newStamp(objNew(), time);
230
+ const stampNewMap = (time = EMPTY_STRING) => [mapNew(), time, 0];
231
+ const stampMapToObjWithHash = (
232
+ [map, time, hash],
233
+ mapper = stampCloneWithHash,
234
+ ) => [mapToObj(map, mapper), time, hash];
235
+ const stampMapToObjWithoutHash = (
236
+ [map, time],
237
+ mapper = stampCloneWithoutHash,
238
+ ) => newStamp(mapToObj(map, mapper), time);
239
+ const stampValidate = (stamp, validateThing) =>
240
+ isArray(stamp) &&
241
+ size(stamp) == 3 &&
242
+ isString(stamp[1]) &&
243
+ getTypeOf(stamp[2]) == NUMBER &&
244
+ isFiniteNumber(stamp[2]) &&
245
+ validateThing(stamp[0]);
246
+
247
+ const INTEGER = /^\d+$/;
248
+ const getPoolFunctions = () => {
249
+ const pool = [];
250
+ let nextId = 0;
251
+ return [
252
+ (reuse) => (reuse ? arrayShift(pool) : null) ?? EMPTY_STRING + nextId++,
253
+ (id) => {
254
+ if (test(INTEGER, id) && size(pool) < 1e3) {
255
+ arrayPush(pool, id);
256
+ }
257
+ },
258
+ ];
259
+ };
260
+
261
+ const getWildcardedLeaves = (deepIdSet, path = [EMPTY_STRING]) => {
262
+ const leaves = [];
263
+ const deep = (node, p) =>
264
+ p == size(path)
265
+ ? arrayPush(leaves, node)
266
+ : path[p] === null
267
+ ? collForEach(node, (node2) => deep(node2, p + 1))
268
+ : arrayForEach([path[p], null], (id) => deep(mapGet(node, id), p + 1));
269
+ deep(deepIdSet, 0);
270
+ return leaves;
271
+ };
272
+ const getListenerFunctions = (getThing) => {
273
+ let thing;
274
+ const [getId, releaseId] = getPoolFunctions();
275
+ const allListeners = mapNew();
276
+ const addListener = (
277
+ listener,
278
+ idSetNode,
279
+ path,
280
+ pathGetters = [],
281
+ extraArgsGetter = () => [],
282
+ ) => {
283
+ thing ??= getThing();
284
+ const id = getId(1);
285
+ mapSet(allListeners, id, [
286
+ listener,
287
+ idSetNode,
288
+ path,
289
+ pathGetters,
290
+ extraArgsGetter,
291
+ ]);
292
+ setAdd(visitTree(idSetNode, path ?? [EMPTY_STRING], setNew), id);
293
+ return id;
294
+ };
295
+ const callListeners = (idSetNode, ids, ...extraArgs) =>
296
+ arrayForEach(getWildcardedLeaves(idSetNode, ids), (set) =>
297
+ collForEach(set, (id) =>
298
+ mapGet(allListeners, id)[0](thing, ...(ids ?? []), ...extraArgs),
299
+ ),
300
+ );
301
+ const delListener = (id) =>
302
+ ifNotUndefined(mapGet(allListeners, id), ([, idSetNode, idOrNulls]) => {
303
+ visitTree(idSetNode, idOrNulls ?? [EMPTY_STRING], void 0, (idSet) => {
304
+ collDel(idSet, id);
305
+ return collIsEmpty(idSet) ? 1 : 0;
306
+ });
307
+ mapSet(allListeners, id);
308
+ releaseId(id);
309
+ return idOrNulls;
310
+ });
311
+ const callListener = (id) =>
312
+ ifNotUndefined(
313
+ mapGet(allListeners, id),
314
+ ([listener, , path = [], pathGetters, extraArgsGetter]) => {
315
+ const callWithIds = (...ids) => {
316
+ const index = size(ids);
317
+ index == size(path)
318
+ ? listener(thing, ...ids, ...extraArgsGetter(ids))
319
+ : isUndefined(path[index])
320
+ ? arrayForEach(pathGetters[index]?.(...ids) ?? [], (id2) =>
321
+ callWithIds(...ids, id2),
322
+ )
323
+ : callWithIds(...ids, path[index]);
324
+ };
325
+ callWithIds();
326
+ },
327
+ );
328
+ return [addListener, callListeners, delListener, callListener];
329
+ };
330
+
331
+ const pairNew = (value) => [value, value];
332
+ const pairCollSize2 = (pair, func = collSize2) => func(pair[0]) + func(pair[1]);
333
+ const pairNewMap = () => [mapNew(), mapNew()];
334
+ const pairClone = (array) => [...array];
335
+ const pairIsEqual = ([entry1, entry2]) => entry1 === entry2;
336
+
337
+ const getCellOrValueType = (cellOrValue) => {
338
+ const type = getTypeOf(cellOrValue);
339
+ return isTypeStringOrBoolean(type) ||
340
+ (type == NUMBER && isFiniteNumber(cellOrValue))
341
+ ? type
342
+ : void 0;
343
+ };
344
+ const isCellOrValueOrNullOrUndefined = (cellOrValue) =>
345
+ isUndefined(cellOrValue) || !isUndefined(getCellOrValueType(cellOrValue));
346
+ const setOrDelCell = (store, tableId, rowId, cellId, cell) =>
347
+ isUndefined(cell)
348
+ ? store.delCell(tableId, rowId, cellId, true)
349
+ : store.setCell(tableId, rowId, cellId, cell);
350
+ const setOrDelValue = (store, valueId, value) =>
351
+ isUndefined(value) ? store.delValue(valueId) : store.setValue(valueId, value);
352
+
353
+ const jsonStringWithMap = (obj) =>
354
+ JSON.stringify(obj, (_key, value) =>
355
+ isInstanceOf(value, Map) ? object.fromEntries([...value]) : value,
356
+ );
357
+ const jsonParse = JSON.parse;
358
+
359
+ const defaultSorter = (sortKey1, sortKey2) =>
360
+ (sortKey1 ?? 0) < (sortKey2 ?? 0) ? -1 : 1;
361
+
362
+ const idsChanged = (changedIds, id2, addedOrRemoved) =>
363
+ mapSet(
364
+ changedIds,
365
+ id2,
366
+ mapGet(changedIds, id2) == -addedOrRemoved ? void 0 : addedOrRemoved,
367
+ );
368
+ const createStore = () => {
369
+ let hasTablesSchema;
370
+ let hasValuesSchema;
371
+ let hadTables = false;
372
+ let hadValues = false;
373
+ let transactions = 0;
374
+ let internalListeners = [];
375
+ const changedTableIds = mapNew();
376
+ const changedTableCellIds = mapNew();
377
+ const changedRowCount = mapNew();
378
+ const changedRowIds = mapNew();
379
+ const changedCellIds = mapNew();
380
+ const changedCells = mapNew();
381
+ const changedValueIds = mapNew();
382
+ const changedValues = mapNew();
383
+ const invalidCells = mapNew();
384
+ const invalidValues = mapNew();
385
+ const tablesSchemaMap = mapNew();
386
+ const tablesSchemaRowCache = mapNew();
387
+ const valuesSchemaMap = mapNew();
388
+ const valuesDefaulted = mapNew();
389
+ const valuesNonDefaulted = setNew();
390
+ const tablePoolFunctions = mapNew();
391
+ const tableCellIds = mapNew();
392
+ const tablesMap = mapNew();
393
+ const valuesMap = mapNew();
394
+ const hasTablesListeners = pairNewMap();
395
+ const tablesListeners = pairNewMap();
396
+ const tableIdsListeners = pairNewMap();
397
+ const hasTableListeners = pairNewMap();
398
+ const tableListeners = pairNewMap();
399
+ const tableCellIdsListeners = pairNewMap();
400
+ const hasTableCellListeners = pairNewMap();
401
+ const rowCountListeners = pairNewMap();
402
+ const rowIdsListeners = pairNewMap();
403
+ const sortedRowIdsListeners = pairNewMap();
404
+ const hasRowListeners = pairNewMap();
405
+ const rowListeners = pairNewMap();
406
+ const cellIdsListeners = pairNewMap();
407
+ const hasCellListeners = pairNewMap();
408
+ const cellListeners = pairNewMap();
409
+ const invalidCellListeners = pairNewMap();
410
+ const invalidValueListeners = pairNewMap();
411
+ const hasValuesListeners = pairNewMap();
412
+ const valuesListeners = pairNewMap();
413
+ const valueIdsListeners = pairNewMap();
414
+ const hasValueListeners = pairNewMap();
415
+ const valueListeners = pairNewMap();
416
+ const startTransactionListeners = mapNew();
417
+ const finishTransactionListeners = pairNewMap();
418
+ const [addListener, callListeners, delListenerImpl, callListenerImpl] =
419
+ getListenerFunctions(() => store);
420
+ const validateTablesSchema = (tableSchema) =>
421
+ objValidate(tableSchema, (tableSchema2) =>
422
+ objValidate(tableSchema2, validateCellOrValueSchema),
423
+ );
424
+ const validateValuesSchema = (valuesSchema) =>
425
+ objValidate(valuesSchema, validateCellOrValueSchema);
426
+ const validateCellOrValueSchema = (schema) => {
427
+ if (!objValidate(schema, (_child, id2) => arrayHas([TYPE, DEFAULT], id2))) {
428
+ return false;
429
+ }
430
+ const type = schema[TYPE];
431
+ if (!isTypeStringOrBoolean(type) && type != NUMBER) {
432
+ return false;
433
+ }
434
+ if (getCellOrValueType(schema[DEFAULT]) != type) {
435
+ objDel(schema, DEFAULT);
436
+ }
437
+ return true;
438
+ };
439
+ const validateTables = (tables) =>
440
+ objValidate(tables, validateTable, cellInvalid);
441
+ const validateTable = (table, tableId) =>
442
+ (!hasTablesSchema ||
443
+ collHas(tablesSchemaMap, tableId) ||
444
+ cellInvalid(tableId)) &&
445
+ objValidate(
446
+ table,
447
+ (row, rowId) => validateRow(tableId, rowId, row),
448
+ () => cellInvalid(tableId),
449
+ );
450
+ const validateRow = (tableId, rowId, row, skipDefaults) =>
451
+ objValidate(
452
+ skipDefaults ? row : addDefaultsToRow(row, tableId, rowId),
453
+ (cell, cellId) =>
454
+ ifNotUndefined(
455
+ getValidatedCell(tableId, rowId, cellId, cell),
456
+ (validCell) => {
457
+ row[cellId] = validCell;
458
+ return true;
459
+ },
460
+ () => false,
461
+ ),
462
+ () => cellInvalid(tableId, rowId),
463
+ );
464
+ const getValidatedCell = (tableId, rowId, cellId, cell) =>
465
+ hasTablesSchema
466
+ ? ifNotUndefined(
467
+ mapGet(mapGet(tablesSchemaMap, tableId), cellId),
468
+ (cellSchema) =>
469
+ getCellOrValueType(cell) != cellSchema[TYPE]
470
+ ? cellInvalid(tableId, rowId, cellId, cell, cellSchema[DEFAULT])
471
+ : cell,
472
+ () => cellInvalid(tableId, rowId, cellId, cell),
473
+ )
474
+ : isUndefined(getCellOrValueType(cell))
475
+ ? cellInvalid(tableId, rowId, cellId, cell)
476
+ : cell;
477
+ const validateValues = (values, skipDefaults) =>
478
+ objValidate(
479
+ skipDefaults ? values : addDefaultsToValues(values),
480
+ (value, valueId) =>
481
+ ifNotUndefined(
482
+ getValidatedValue(valueId, value),
483
+ (validValue) => {
484
+ values[valueId] = validValue;
485
+ return true;
486
+ },
487
+ () => false,
488
+ ),
489
+ () => valueInvalid(),
490
+ );
491
+ const getValidatedValue = (valueId, value) =>
492
+ hasValuesSchema
493
+ ? ifNotUndefined(
494
+ mapGet(valuesSchemaMap, valueId),
495
+ (valueSchema) =>
496
+ getCellOrValueType(value) != valueSchema[TYPE]
497
+ ? valueInvalid(valueId, value, valueSchema[DEFAULT])
498
+ : value,
499
+ () => valueInvalid(valueId, value),
500
+ )
501
+ : isUndefined(getCellOrValueType(value))
502
+ ? valueInvalid(valueId, value)
503
+ : value;
504
+ const addDefaultsToRow = (row, tableId, rowId) => {
505
+ ifNotUndefined(
506
+ mapGet(tablesSchemaRowCache, tableId),
507
+ ([rowDefaulted, rowNonDefaulted]) => {
508
+ collForEach(rowDefaulted, (cell, cellId) => {
509
+ if (!objHas(row, cellId)) {
510
+ row[cellId] = cell;
511
+ }
512
+ });
513
+ collForEach(rowNonDefaulted, (cellId) => {
514
+ if (!objHas(row, cellId)) {
515
+ cellInvalid(tableId, rowId, cellId);
516
+ }
517
+ });
518
+ },
519
+ );
520
+ return row;
521
+ };
522
+ const addDefaultsToValues = (values) => {
523
+ if (hasValuesSchema) {
524
+ collForEach(valuesDefaulted, (value, valueId) => {
525
+ if (!objHas(values, valueId)) {
526
+ values[valueId] = value;
527
+ }
528
+ });
529
+ collForEach(valuesNonDefaulted, (valueId) => {
530
+ if (!objHas(values, valueId)) {
531
+ valueInvalid(valueId);
532
+ }
533
+ });
534
+ }
535
+ return values;
536
+ };
537
+ const setValidTablesSchema = (tablesSchema) =>
538
+ mapMatch(
539
+ tablesSchemaMap,
540
+ tablesSchema,
541
+ (_tablesSchema, tableId, tableSchema) => {
542
+ const rowDefaulted = mapNew();
543
+ const rowNonDefaulted = setNew();
544
+ mapMatch(
545
+ mapEnsure(tablesSchemaMap, tableId, mapNew),
546
+ tableSchema,
547
+ (tableSchemaMap, cellId, cellSchema) => {
548
+ mapSet(tableSchemaMap, cellId, cellSchema);
549
+ ifNotUndefined(
550
+ cellSchema[DEFAULT],
551
+ (def) => mapSet(rowDefaulted, cellId, def),
552
+ () => setAdd(rowNonDefaulted, cellId),
553
+ );
554
+ },
555
+ );
556
+ mapSet(tablesSchemaRowCache, tableId, [rowDefaulted, rowNonDefaulted]);
557
+ },
558
+ (_tablesSchema, tableId) => {
559
+ mapSet(tablesSchemaMap, tableId);
560
+ mapSet(tablesSchemaRowCache, tableId);
561
+ },
562
+ );
563
+ const setValidValuesSchema = (valuesSchema) =>
564
+ mapMatch(
565
+ valuesSchemaMap,
566
+ valuesSchema,
567
+ (_valuesSchema, valueId, valueSchema) => {
568
+ mapSet(valuesSchemaMap, valueId, valueSchema);
569
+ ifNotUndefined(
570
+ valueSchema[DEFAULT],
571
+ (def) => mapSet(valuesDefaulted, valueId, def),
572
+ () => setAdd(valuesNonDefaulted, valueId),
573
+ );
574
+ },
575
+ (_valuesSchema, valueId) => {
576
+ mapSet(valuesSchemaMap, valueId);
577
+ mapSet(valuesDefaulted, valueId);
578
+ collDel(valuesNonDefaulted, valueId);
579
+ },
580
+ );
581
+ const setOrDelTables = (tables) =>
582
+ objIsEmpty(tables) ? delTables() : setTables(tables);
583
+ const setValidTables = (tables) =>
584
+ mapMatch(
585
+ tablesMap,
586
+ tables,
587
+ (_tables, tableId, table) => setValidTable(tableId, table),
588
+ (_tables, tableId) => delValidTable(tableId),
589
+ );
590
+ const setValidTable = (tableId, table) =>
591
+ mapMatch(
592
+ mapEnsure(tablesMap, tableId, () => {
593
+ tableIdsChanged(tableId, 1);
594
+ mapSet(tablePoolFunctions, tableId, getPoolFunctions());
595
+ mapSet(tableCellIds, tableId, mapNew());
596
+ return mapNew();
597
+ }),
598
+ table,
599
+ (tableMap, rowId, row) => setValidRow(tableId, tableMap, rowId, row),
600
+ (tableMap, rowId) => delValidRow(tableId, tableMap, rowId),
601
+ );
602
+ const setValidRow = (tableId, tableMap, rowId, row, forceDel) =>
603
+ mapMatch(
604
+ mapEnsure(tableMap, rowId, () => {
605
+ rowIdsChanged(tableId, rowId, 1);
606
+ return mapNew();
607
+ }),
608
+ row,
609
+ (rowMap, cellId, cell) =>
610
+ setValidCell(tableId, rowId, rowMap, cellId, cell),
611
+ (rowMap, cellId) =>
612
+ delValidCell(tableId, tableMap, rowId, rowMap, cellId, forceDel),
613
+ );
614
+ const setValidCell = (tableId, rowId, rowMap, cellId, cell) => {
615
+ if (!collHas(rowMap, cellId)) {
616
+ cellIdsChanged(tableId, rowId, cellId, 1);
617
+ }
618
+ const oldCell = mapGet(rowMap, cellId);
619
+ if (cell !== oldCell) {
620
+ cellChanged(tableId, rowId, cellId, oldCell, cell);
621
+ mapSet(rowMap, cellId, cell);
622
+ }
623
+ };
624
+ const setCellIntoDefaultRow = (tableId, tableMap, rowId, cellId, validCell) =>
625
+ ifNotUndefined(
626
+ mapGet(tableMap, rowId),
627
+ (rowMap) => setValidCell(tableId, rowId, rowMap, cellId, validCell),
628
+ () =>
629
+ setValidRow(
630
+ tableId,
631
+ tableMap,
632
+ rowId,
633
+ addDefaultsToRow({[cellId]: validCell}, tableId, rowId),
634
+ ),
635
+ );
636
+ const setOrDelValues = (values) =>
637
+ objIsEmpty(values) ? delValues() : setValues(values);
638
+ const setValidValues = (values) =>
639
+ mapMatch(
640
+ valuesMap,
641
+ values,
642
+ (_valuesMap, valueId, value) => setValidValue(valueId, value),
643
+ (_valuesMap, valueId) => delValidValue(valueId),
644
+ );
645
+ const setValidValue = (valueId, value) => {
646
+ if (!collHas(valuesMap, valueId)) {
647
+ valueIdsChanged(valueId, 1);
648
+ }
649
+ const oldValue = mapGet(valuesMap, valueId);
650
+ if (value !== oldValue) {
651
+ valueChanged(valueId, oldValue, value);
652
+ mapSet(valuesMap, valueId, value);
653
+ }
654
+ };
655
+ const getNewRowId = (tableId, reuse) => {
656
+ const [getId] = mapGet(tablePoolFunctions, tableId);
657
+ const rowId = getId(reuse);
658
+ if (!collHas(mapGet(tablesMap, tableId), rowId)) {
659
+ return rowId;
660
+ }
661
+ return getNewRowId(tableId, reuse);
662
+ };
663
+ const getOrCreateTable = (tableId) =>
664
+ mapGet(tablesMap, tableId) ?? setValidTable(tableId, {});
665
+ const delValidTable = (tableId) => setValidTable(tableId, {});
666
+ const delValidRow = (tableId, tableMap, rowId) => {
667
+ const [, releaseId] = mapGet(tablePoolFunctions, tableId);
668
+ releaseId(rowId);
669
+ setValidRow(tableId, tableMap, rowId, {}, true);
670
+ };
671
+ const delValidCell = (tableId, table, rowId, row, cellId, forceDel) => {
672
+ const defaultCell = mapGet(
673
+ mapGet(tablesSchemaRowCache, tableId)?.[0],
674
+ cellId,
675
+ );
676
+ if (!isUndefined(defaultCell) && !forceDel) {
677
+ return setValidCell(tableId, rowId, row, cellId, defaultCell);
678
+ }
679
+ const delCell2 = (cellId2) => {
680
+ cellChanged(tableId, rowId, cellId2, mapGet(row, cellId2));
681
+ cellIdsChanged(tableId, rowId, cellId2, -1);
682
+ mapSet(row, cellId2);
683
+ };
684
+ isUndefined(defaultCell) ? delCell2(cellId) : mapForEach(row, delCell2);
685
+ if (collIsEmpty(row)) {
686
+ rowIdsChanged(tableId, rowId, -1);
687
+ if (collIsEmpty(mapSet(table, rowId))) {
688
+ tableIdsChanged(tableId, -1);
689
+ mapSet(tablesMap, tableId);
690
+ mapSet(tablePoolFunctions, tableId);
691
+ mapSet(tableCellIds, tableId);
692
+ }
693
+ }
694
+ };
695
+ const delValidValue = (valueId) => {
696
+ const defaultValue = mapGet(valuesDefaulted, valueId);
697
+ if (!isUndefined(defaultValue)) {
698
+ return setValidValue(valueId, defaultValue);
699
+ }
700
+ valueChanged(valueId, mapGet(valuesMap, valueId));
701
+ valueIdsChanged(valueId, -1);
702
+ mapSet(valuesMap, valueId);
703
+ };
704
+ const tableIdsChanged = (tableId, addedOrRemoved) =>
705
+ idsChanged(changedTableIds, tableId, addedOrRemoved);
706
+ const rowIdsChanged = (tableId, rowId, addedOrRemoved) =>
707
+ idsChanged(
708
+ mapEnsure(changedRowIds, tableId, mapNew),
709
+ rowId,
710
+ addedOrRemoved,
711
+ ) &&
712
+ mapSet(
713
+ changedRowCount,
714
+ tableId,
715
+ mapEnsure(changedRowCount, tableId, () => 0) + addedOrRemoved,
716
+ );
717
+ const cellIdsChanged = (tableId, rowId, cellId, addedOrRemoved) => {
718
+ const cellIds = mapGet(tableCellIds, tableId);
719
+ const count = mapGet(cellIds, cellId) ?? 0;
720
+ if (
721
+ (count == 0 && addedOrRemoved == 1) ||
722
+ (count == 1 && addedOrRemoved == -1)
723
+ ) {
724
+ idsChanged(
725
+ mapEnsure(changedTableCellIds, tableId, mapNew),
726
+ cellId,
727
+ addedOrRemoved,
728
+ );
729
+ }
730
+ mapSet(
731
+ cellIds,
732
+ cellId,
733
+ count != -addedOrRemoved ? count + addedOrRemoved : null,
734
+ );
735
+ idsChanged(
736
+ mapEnsure(mapEnsure(changedCellIds, tableId, mapNew), rowId, mapNew),
737
+ cellId,
738
+ addedOrRemoved,
739
+ );
740
+ };
741
+ const cellChanged = (tableId, rowId, cellId, oldCell, newCell) => {
742
+ mapEnsure(
743
+ mapEnsure(mapEnsure(changedCells, tableId, mapNew), rowId, mapNew),
744
+ cellId,
745
+ () => [oldCell, 0],
746
+ )[1] = newCell;
747
+ internalListeners[3]?.(tableId, rowId, cellId, newCell);
748
+ };
749
+ const valueIdsChanged = (valueId, addedOrRemoved) =>
750
+ idsChanged(changedValueIds, valueId, addedOrRemoved);
751
+ const valueChanged = (valueId, oldValue, newValue) => {
752
+ mapEnsure(changedValues, valueId, () => [oldValue, 0])[1] = newValue;
753
+ internalListeners[4]?.(valueId, newValue);
754
+ };
755
+ const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
756
+ arrayPush(
757
+ mapEnsure(
758
+ mapEnsure(mapEnsure(invalidCells, tableId, mapNew), rowId, mapNew),
759
+ cellId,
760
+ () => [],
761
+ ),
762
+ invalidCell,
763
+ );
764
+ return defaultedCell;
765
+ };
766
+ const valueInvalid = (valueId, invalidValue, defaultedValue) => {
767
+ arrayPush(
768
+ mapEnsure(invalidValues, valueId, () => []),
769
+ invalidValue,
770
+ );
771
+ return defaultedValue;
772
+ };
773
+ const getCellChange = (tableId, rowId, cellId) =>
774
+ ifNotUndefined(
775
+ mapGet(mapGet(mapGet(changedCells, tableId), rowId), cellId),
776
+ ([oldCell, newCell]) => [true, oldCell, newCell],
777
+ () => [false, ...pairNew(getCell(tableId, rowId, cellId))],
778
+ );
779
+ const getValueChange = (valueId) =>
780
+ ifNotUndefined(
781
+ mapGet(changedValues, valueId),
782
+ ([oldValue, newValue]) => [true, oldValue, newValue],
783
+ () => [false, ...pairNew(getValue(valueId))],
784
+ );
785
+ const callInvalidCellListeners = (mutator) =>
786
+ !collIsEmpty(invalidCells) && !collIsEmpty(invalidCellListeners[mutator])
787
+ ? collForEach(
788
+ mutator ? mapClone3(invalidCells) : invalidCells,
789
+ (rows, tableId) =>
790
+ collForEach(rows, (cells, rowId) =>
791
+ collForEach(cells, (invalidCell, cellId) =>
792
+ callListeners(
793
+ invalidCellListeners[mutator],
794
+ [tableId, rowId, cellId],
795
+ invalidCell,
796
+ ),
797
+ ),
798
+ ),
799
+ )
800
+ : 0;
801
+ const callInvalidValueListeners = (mutator) =>
802
+ !collIsEmpty(invalidValues) && !collIsEmpty(invalidValueListeners[mutator])
803
+ ? collForEach(
804
+ mutator ? mapClone(invalidValues) : invalidValues,
805
+ (invalidValue, valueId) =>
806
+ callListeners(
807
+ invalidValueListeners[mutator],
808
+ [valueId],
809
+ invalidValue,
810
+ ),
811
+ )
812
+ : 0;
813
+ const callIdsAndHasListenersIfChanged = (
814
+ changedIds,
815
+ idListeners,
816
+ hasListeners,
817
+ ids,
818
+ ) => {
819
+ if (!collIsEmpty(changedIds)) {
820
+ callListeners(idListeners, ids, () => mapToObj(changedIds));
821
+ mapForEach(changedIds, (changedId, changed) =>
822
+ callListeners(hasListeners, [...(ids ?? []), changedId], changed == 1),
823
+ );
824
+ return 1;
825
+ }
826
+ };
827
+ const callTabularListenersForChanges = (mutator) => {
828
+ const hasTablesNow = hasTables();
829
+ if (hasTablesNow != hadTables) {
830
+ callListeners(hasTablesListeners[mutator], void 0, hasTablesNow);
831
+ }
832
+ const emptySortedRowIdListeners = collIsEmpty(
833
+ sortedRowIdsListeners[mutator],
834
+ );
835
+ const emptyIdAndHasListeners =
836
+ collIsEmpty(cellIdsListeners[mutator]) &&
837
+ collIsEmpty(hasCellListeners[mutator]) &&
838
+ collIsEmpty(rowIdsListeners[mutator]) &&
839
+ collIsEmpty(hasRowListeners[mutator]) &&
840
+ collIsEmpty(tableCellIdsListeners[mutator]) &&
841
+ collIsEmpty(hasTableCellListeners[mutator]) &&
842
+ collIsEmpty(rowCountListeners[mutator]) &&
843
+ emptySortedRowIdListeners &&
844
+ collIsEmpty(tableIdsListeners[mutator]) &&
845
+ collIsEmpty(hasTableListeners[mutator]);
846
+ const emptyOtherListeners =
847
+ collIsEmpty(cellListeners[mutator]) &&
848
+ collIsEmpty(rowListeners[mutator]) &&
849
+ collIsEmpty(tableListeners[mutator]) &&
850
+ collIsEmpty(tablesListeners[mutator]);
851
+ if (!emptyIdAndHasListeners || !emptyOtherListeners) {
852
+ const changes = mutator
853
+ ? [
854
+ mapClone(changedTableIds),
855
+ mapClone2(changedTableCellIds),
856
+ mapClone(changedRowCount),
857
+ mapClone2(changedRowIds),
858
+ mapClone3(changedCellIds),
859
+ mapClone3(changedCells),
860
+ ]
861
+ : [
862
+ changedTableIds,
863
+ changedTableCellIds,
864
+ changedRowCount,
865
+ changedRowIds,
866
+ changedCellIds,
867
+ changedCells,
868
+ ];
869
+ if (!emptyIdAndHasListeners) {
870
+ callIdsAndHasListenersIfChanged(
871
+ changes[0],
872
+ tableIdsListeners[mutator],
873
+ hasTableListeners[mutator],
874
+ );
875
+ collForEach(changes[1], (changedIds, tableId) =>
876
+ callIdsAndHasListenersIfChanged(
877
+ changedIds,
878
+ tableCellIdsListeners[mutator],
879
+ hasTableCellListeners[mutator],
880
+ [tableId],
881
+ ),
882
+ );
883
+ collForEach(changes[2], (changedCount, tableId) => {
884
+ if (changedCount != 0) {
885
+ callListeners(
886
+ rowCountListeners[mutator],
887
+ [tableId],
888
+ getRowCount(tableId),
889
+ );
890
+ }
891
+ });
892
+ const calledSortableTableIds = setNew();
893
+ collForEach(changes[3], (changedIds, tableId) => {
894
+ if (
895
+ callIdsAndHasListenersIfChanged(
896
+ changedIds,
897
+ rowIdsListeners[mutator],
898
+ hasRowListeners[mutator],
899
+ [tableId],
900
+ ) &&
901
+ !emptySortedRowIdListeners
902
+ ) {
903
+ callListeners(sortedRowIdsListeners[mutator], [tableId, null]);
904
+ setAdd(calledSortableTableIds, tableId);
905
+ }
906
+ });
907
+ if (!emptySortedRowIdListeners) {
908
+ collForEach(changes[5], (rows, tableId) => {
909
+ if (!collHas(calledSortableTableIds, tableId)) {
910
+ const sortableCellIds = setNew();
911
+ collForEach(rows, (cells) =>
912
+ collForEach(cells, ([oldCell, newCell], cellId) =>
913
+ newCell !== oldCell
914
+ ? setAdd(sortableCellIds, cellId)
915
+ : collDel(cells, cellId),
916
+ ),
917
+ );
918
+ collForEach(sortableCellIds, (cellId) =>
919
+ callListeners(sortedRowIdsListeners[mutator], [
920
+ tableId,
921
+ cellId,
922
+ ]),
923
+ );
924
+ }
925
+ });
926
+ }
927
+ collForEach(changes[4], (rowCellIds, tableId) =>
928
+ collForEach(rowCellIds, (changedIds, rowId) =>
929
+ callIdsAndHasListenersIfChanged(
930
+ changedIds,
931
+ cellIdsListeners[mutator],
932
+ hasCellListeners[mutator],
933
+ [tableId, rowId],
934
+ ),
935
+ ),
936
+ );
937
+ }
938
+ if (!emptyOtherListeners) {
939
+ let tablesChanged;
940
+ collForEach(changes[5], (rows, tableId) => {
941
+ let tableChanged;
942
+ collForEach(rows, (cells, rowId) => {
943
+ let rowChanged;
944
+ collForEach(cells, ([oldCell, newCell], cellId) => {
945
+ if (newCell !== oldCell) {
946
+ callListeners(
947
+ cellListeners[mutator],
948
+ [tableId, rowId, cellId],
949
+ newCell,
950
+ oldCell,
951
+ getCellChange,
952
+ );
953
+ tablesChanged = tableChanged = rowChanged = 1;
954
+ }
955
+ });
956
+ if (rowChanged) {
957
+ callListeners(
958
+ rowListeners[mutator],
959
+ [tableId, rowId],
960
+ getCellChange,
961
+ );
962
+ }
963
+ });
964
+ if (tableChanged) {
965
+ callListeners(tableListeners[mutator], [tableId], getCellChange);
966
+ }
967
+ });
968
+ if (tablesChanged) {
969
+ callListeners(tablesListeners[mutator], void 0, getCellChange);
970
+ }
971
+ }
972
+ }
973
+ };
974
+ const callValuesListenersForChanges = (mutator) => {
975
+ const hasValuesNow = hasValues();
976
+ if (hasValuesNow != hadValues) {
977
+ callListeners(hasValuesListeners[mutator], void 0, hasValuesNow);
978
+ }
979
+ const emptyIdAndHasListeners =
980
+ collIsEmpty(valueIdsListeners[mutator]) &&
981
+ collIsEmpty(hasValueListeners[mutator]);
982
+ const emptyOtherListeners =
983
+ collIsEmpty(valueListeners[mutator]) &&
984
+ collIsEmpty(valuesListeners[mutator]);
985
+ if (!emptyIdAndHasListeners || !emptyOtherListeners) {
986
+ const changes = mutator
987
+ ? [mapClone(changedValueIds), mapClone(changedValues)]
988
+ : [changedValueIds, changedValues];
989
+ if (!emptyIdAndHasListeners) {
990
+ callIdsAndHasListenersIfChanged(
991
+ changes[0],
992
+ valueIdsListeners[mutator],
993
+ hasValueListeners[mutator],
994
+ );
995
+ }
996
+ if (!emptyOtherListeners) {
997
+ let valuesChanged;
998
+ collForEach(changes[1], ([oldValue, newValue], valueId) => {
999
+ if (newValue !== oldValue) {
1000
+ callListeners(
1001
+ valueListeners[mutator],
1002
+ [valueId],
1003
+ newValue,
1004
+ oldValue,
1005
+ getValueChange,
1006
+ );
1007
+ valuesChanged = 1;
1008
+ }
1009
+ });
1010
+ if (valuesChanged) {
1011
+ callListeners(valuesListeners[mutator], void 0, getValueChange);
1012
+ }
1013
+ }
1014
+ }
1015
+ };
1016
+ const fluentTransaction = (actions, ...args) => {
1017
+ transaction(() => actions(...arrayMap(args, id)));
1018
+ return store;
1019
+ };
1020
+ const getContent = () => [getTables(), getValues()];
1021
+ const getTables = () => mapToObj3(tablesMap);
1022
+ const getTableIds = () => mapKeys(tablesMap);
1023
+ const getTable = (tableId) => mapToObj2(mapGet(tablesMap, id(tableId)));
1024
+ const getTableCellIds = (tableId) =>
1025
+ mapKeys(mapGet(tableCellIds, id(tableId)));
1026
+ const getRowCount = (tableId) => collSize(mapGet(tablesMap, id(tableId)));
1027
+ const getRowIds = (tableId) => mapKeys(mapGet(tablesMap, id(tableId)));
1028
+ const getSortedRowIds = (tableId, cellId, descending, offset = 0, limit) =>
1029
+ arrayMap(
1030
+ slice(
1031
+ arraySort(
1032
+ mapMap(mapGet(tablesMap, id(tableId)), (row, rowId) => [
1033
+ isUndefined(cellId) ? rowId : mapGet(row, id(cellId)),
1034
+ rowId,
1035
+ ]),
1036
+ ([cell1], [cell2]) =>
1037
+ defaultSorter(cell1, cell2) * (descending ? -1 : 1),
1038
+ ),
1039
+ offset,
1040
+ isUndefined(limit) ? limit : offset + limit,
1041
+ ),
1042
+ ([, rowId]) => rowId,
1043
+ );
1044
+ const getRow = (tableId, rowId) =>
1045
+ mapToObj(mapGet(mapGet(tablesMap, id(tableId)), id(rowId)));
1046
+ const getCellIds = (tableId, rowId) =>
1047
+ mapKeys(mapGet(mapGet(tablesMap, id(tableId)), id(rowId)));
1048
+ const getCell = (tableId, rowId, cellId) =>
1049
+ mapGet(mapGet(mapGet(tablesMap, id(tableId)), id(rowId)), id(cellId));
1050
+ const getValues = () => mapToObj(valuesMap);
1051
+ const getValueIds = () => mapKeys(valuesMap);
1052
+ const getValue = (valueId) => mapGet(valuesMap, id(valueId));
1053
+ const hasTables = () => !collIsEmpty(tablesMap);
1054
+ const hasTable = (tableId) => collHas(tablesMap, id(tableId));
1055
+ const hasTableCell = (tableId, cellId) =>
1056
+ collHas(mapGet(tableCellIds, id(tableId)), id(cellId));
1057
+ const hasRow = (tableId, rowId) =>
1058
+ collHas(mapGet(tablesMap, id(tableId)), id(rowId));
1059
+ const hasCell = (tableId, rowId, cellId) =>
1060
+ collHas(mapGet(mapGet(tablesMap, id(tableId)), id(rowId)), id(cellId));
1061
+ const hasValues = () => !collIsEmpty(valuesMap);
1062
+ const hasValue = (valueId) => collHas(valuesMap, id(valueId));
1063
+ const getTablesJson = () => jsonStringWithMap(tablesMap);
1064
+ const getValuesJson = () => jsonStringWithMap(valuesMap);
1065
+ const getJson = () => jsonStringWithMap([tablesMap, valuesMap]);
1066
+ const getTablesSchemaJson = () => jsonStringWithMap(tablesSchemaMap);
1067
+ const getValuesSchemaJson = () => jsonStringWithMap(valuesSchemaMap);
1068
+ const getSchemaJson = () =>
1069
+ jsonStringWithMap([tablesSchemaMap, valuesSchemaMap]);
1070
+ const setContent = ([tables, values]) =>
1071
+ fluentTransaction(() => {
1072
+ (objIsEmpty(tables) ? delTables : setTables)(tables);
1073
+ (objIsEmpty(values) ? delValues : setValues)(values);
1074
+ });
1075
+ const setTables = (tables) =>
1076
+ fluentTransaction(() =>
1077
+ validateTables(tables) ? setValidTables(tables) : 0,
1078
+ );
1079
+ const setTable = (tableId, table) =>
1080
+ fluentTransaction(
1081
+ (tableId2) =>
1082
+ validateTable(table, tableId2) ? setValidTable(tableId2, table) : 0,
1083
+ tableId,
1084
+ );
1085
+ const setRow = (tableId, rowId, row) =>
1086
+ fluentTransaction(
1087
+ (tableId2, rowId2) =>
1088
+ validateRow(tableId2, rowId2, row)
1089
+ ? setValidRow(tableId2, getOrCreateTable(tableId2), rowId2, row)
1090
+ : 0,
1091
+ tableId,
1092
+ rowId,
1093
+ );
1094
+ const addRow = (tableId, row, reuseRowIds = true) =>
1095
+ transaction(() => {
1096
+ let rowId = void 0;
1097
+ if (validateRow(tableId, rowId, row)) {
1098
+ tableId = id(tableId);
1099
+ setValidRow(
1100
+ tableId,
1101
+ getOrCreateTable(tableId),
1102
+ (rowId = getNewRowId(tableId, reuseRowIds ? 1 : 0)),
1103
+ row,
1104
+ );
1105
+ }
1106
+ return rowId;
1107
+ });
1108
+ const setPartialRow = (tableId, rowId, partialRow) =>
1109
+ fluentTransaction(
1110
+ (tableId2, rowId2) => {
1111
+ if (validateRow(tableId2, rowId2, partialRow, 1)) {
1112
+ const table = getOrCreateTable(tableId2);
1113
+ objToArray(partialRow, (cell, cellId) =>
1114
+ setCellIntoDefaultRow(tableId2, table, rowId2, cellId, cell),
1115
+ );
1116
+ }
1117
+ },
1118
+ tableId,
1119
+ rowId,
1120
+ );
1121
+ const setCell = (tableId, rowId, cellId, cell) =>
1122
+ fluentTransaction(
1123
+ (tableId2, rowId2, cellId2) =>
1124
+ ifNotUndefined(
1125
+ getValidatedCell(
1126
+ tableId2,
1127
+ rowId2,
1128
+ cellId2,
1129
+ isFunction(cell) ? cell(getCell(tableId2, rowId2, cellId2)) : cell,
1130
+ ),
1131
+ (validCell) =>
1132
+ setCellIntoDefaultRow(
1133
+ tableId2,
1134
+ getOrCreateTable(tableId2),
1135
+ rowId2,
1136
+ cellId2,
1137
+ validCell,
1138
+ ),
1139
+ ),
1140
+ tableId,
1141
+ rowId,
1142
+ cellId,
1143
+ );
1144
+ const setValues = (values) =>
1145
+ fluentTransaction(() =>
1146
+ validateValues(values) ? setValidValues(values) : 0,
1147
+ );
1148
+ const setPartialValues = (partialValues) =>
1149
+ fluentTransaction(() =>
1150
+ validateValues(partialValues, 1)
1151
+ ? objToArray(partialValues, (value, valueId) =>
1152
+ setValidValue(valueId, value),
1153
+ )
1154
+ : 0,
1155
+ );
1156
+ const setValue = (valueId, value) =>
1157
+ fluentTransaction(
1158
+ (valueId2) =>
1159
+ ifNotUndefined(
1160
+ getValidatedValue(
1161
+ valueId2,
1162
+ isFunction(value) ? value(getValue(valueId2)) : value,
1163
+ ),
1164
+ (validValue) => setValidValue(valueId2, validValue),
1165
+ ),
1166
+ valueId,
1167
+ );
1168
+ const applyChanges = (changes) =>
1169
+ fluentTransaction(() => {
1170
+ objToArray(changes[0], (table, tableId) =>
1171
+ isUndefined(table)
1172
+ ? delTable(tableId)
1173
+ : objToArray(table, (row, rowId) =>
1174
+ isUndefined(row)
1175
+ ? delRow(tableId, rowId)
1176
+ : objToArray(row, (cell, cellId) =>
1177
+ setOrDelCell(store, tableId, rowId, cellId, cell),
1178
+ ),
1179
+ ),
1180
+ );
1181
+ objToArray(changes[1], (value, valueId) =>
1182
+ setOrDelValue(store, valueId, value),
1183
+ );
1184
+ });
1185
+ const setTablesJson = (tablesJson) => {
1186
+ try {
1187
+ setOrDelTables(jsonParse(tablesJson));
1188
+ } catch {}
1189
+ return store;
1190
+ };
1191
+ const setValuesJson = (valuesJson) => {
1192
+ try {
1193
+ setOrDelValues(jsonParse(valuesJson));
1194
+ } catch {}
1195
+ return store;
1196
+ };
1197
+ const setJson = (tablesAndValuesJson) =>
1198
+ fluentTransaction(() => {
1199
+ try {
1200
+ const [tables, values] = jsonParse(tablesAndValuesJson);
1201
+ setOrDelTables(tables);
1202
+ setOrDelValues(values);
1203
+ } catch {
1204
+ setTablesJson(tablesAndValuesJson);
1205
+ }
1206
+ });
1207
+ const setTablesSchema = (tablesSchema) =>
1208
+ fluentTransaction(() => {
1209
+ if ((hasTablesSchema = validateTablesSchema(tablesSchema))) {
1210
+ setValidTablesSchema(tablesSchema);
1211
+ if (!collIsEmpty(tablesMap)) {
1212
+ const tables = getTables();
1213
+ delTables();
1214
+ setTables(tables);
1215
+ }
1216
+ }
1217
+ });
1218
+ const setValuesSchema = (valuesSchema) =>
1219
+ fluentTransaction(() => {
1220
+ if ((hasValuesSchema = validateValuesSchema(valuesSchema))) {
1221
+ const values = getValues();
1222
+ delValuesSchema();
1223
+ delValues();
1224
+ hasValuesSchema = true;
1225
+ setValidValuesSchema(valuesSchema);
1226
+ setValues(values);
1227
+ }
1228
+ });
1229
+ const setSchema = (tablesSchema, valuesSchema) =>
1230
+ fluentTransaction(() => {
1231
+ setTablesSchema(tablesSchema);
1232
+ setValuesSchema(valuesSchema);
1233
+ });
1234
+ const delTables = () => fluentTransaction(() => setValidTables({}));
1235
+ const delTable = (tableId) =>
1236
+ fluentTransaction(
1237
+ (tableId2) =>
1238
+ collHas(tablesMap, tableId2) ? delValidTable(tableId2) : 0,
1239
+ tableId,
1240
+ );
1241
+ const delRow = (tableId, rowId) =>
1242
+ fluentTransaction(
1243
+ (tableId2, rowId2) =>
1244
+ ifNotUndefined(mapGet(tablesMap, tableId2), (tableMap) =>
1245
+ collHas(tableMap, rowId2)
1246
+ ? delValidRow(tableId2, tableMap, rowId2)
1247
+ : 0,
1248
+ ),
1249
+ tableId,
1250
+ rowId,
1251
+ );
1252
+ const delCell = (tableId, rowId, cellId, forceDel) =>
1253
+ fluentTransaction(
1254
+ (tableId2, rowId2, cellId2) =>
1255
+ ifNotUndefined(mapGet(tablesMap, tableId2), (tableMap) =>
1256
+ ifNotUndefined(mapGet(tableMap, rowId2), (rowMap) =>
1257
+ collHas(rowMap, cellId2)
1258
+ ? delValidCell(
1259
+ tableId2,
1260
+ tableMap,
1261
+ rowId2,
1262
+ rowMap,
1263
+ cellId2,
1264
+ forceDel,
1265
+ )
1266
+ : 0,
1267
+ ),
1268
+ ),
1269
+ tableId,
1270
+ rowId,
1271
+ cellId,
1272
+ );
1273
+ const delValues = () => fluentTransaction(() => setValidValues({}));
1274
+ const delValue = (valueId) =>
1275
+ fluentTransaction(
1276
+ (valueId2) =>
1277
+ collHas(valuesMap, valueId2) ? delValidValue(valueId2) : 0,
1278
+ valueId,
1279
+ );
1280
+ const delTablesSchema = () =>
1281
+ fluentTransaction(() => {
1282
+ setValidTablesSchema({});
1283
+ hasTablesSchema = false;
1284
+ });
1285
+ const delValuesSchema = () =>
1286
+ fluentTransaction(() => {
1287
+ setValidValuesSchema({});
1288
+ hasValuesSchema = false;
1289
+ });
1290
+ const delSchema = () =>
1291
+ fluentTransaction(() => {
1292
+ delTablesSchema();
1293
+ delValuesSchema();
1294
+ });
1295
+ const transaction = (actions, doRollback) => {
1296
+ if (transactions != -1) {
1297
+ startTransaction();
1298
+ const result = actions();
1299
+ finishTransaction(doRollback);
1300
+ return result;
1301
+ }
1302
+ };
1303
+ const startTransaction = () => {
1304
+ if (transactions != -1) {
1305
+ transactions++;
1306
+ }
1307
+ if (transactions == 1) {
1308
+ internalListeners[0]?.();
1309
+ callListeners(startTransactionListeners, void 0);
1310
+ }
1311
+ return store;
1312
+ };
1313
+ const getTransactionChanges = () => [
1314
+ mapToObj(
1315
+ changedCells,
1316
+ (table, tableId) =>
1317
+ mapGet(changedTableIds, tableId) === -1
1318
+ ? void 0
1319
+ : mapToObj(
1320
+ table,
1321
+ (row, rowId) =>
1322
+ mapGet(mapGet(changedRowIds, tableId), rowId) === -1
1323
+ ? void 0
1324
+ : mapToObj(
1325
+ row,
1326
+ ([, newCell]) => newCell,
1327
+ (changedCell) => pairIsEqual(changedCell),
1328
+ ),
1329
+ collIsEmpty,
1330
+ objIsEmpty,
1331
+ ),
1332
+ collIsEmpty,
1333
+ objIsEmpty,
1334
+ ),
1335
+ mapToObj(
1336
+ changedValues,
1337
+ ([, newValue]) => newValue,
1338
+ (changedValue) => pairIsEqual(changedValue),
1339
+ ),
1340
+ 1,
1341
+ ];
1342
+ const getTransactionLog = () => [
1343
+ !collIsEmpty(changedCells),
1344
+ !collIsEmpty(changedValues),
1345
+ mapToObj3(changedCells, pairClone, pairIsEqual),
1346
+ mapToObj3(invalidCells),
1347
+ mapToObj(changedValues, pairClone, pairIsEqual),
1348
+ mapToObj(invalidValues),
1349
+ mapToObj(changedTableIds),
1350
+ mapToObj2(changedRowIds),
1351
+ mapToObj3(changedCellIds),
1352
+ mapToObj(changedValueIds),
1353
+ ];
1354
+ const finishTransaction = (doRollback) => {
1355
+ if (transactions > 0) {
1356
+ transactions--;
1357
+ if (transactions == 0) {
1358
+ transactions = 1;
1359
+ callInvalidCellListeners(1);
1360
+ if (!collIsEmpty(changedCells)) {
1361
+ callTabularListenersForChanges(1);
1362
+ }
1363
+ callInvalidValueListeners(1);
1364
+ if (!collIsEmpty(changedValues)) {
1365
+ callValuesListenersForChanges(1);
1366
+ }
1367
+ if (doRollback?.(store)) {
1368
+ collForEach(changedCells, (table, tableId) =>
1369
+ collForEach(table, (row, rowId) =>
1370
+ collForEach(row, ([oldCell], cellId) =>
1371
+ setOrDelCell(store, tableId, rowId, cellId, oldCell),
1372
+ ),
1373
+ ),
1374
+ );
1375
+ collClear(changedCells);
1376
+ collForEach(changedValues, ([oldValue], valueId) =>
1377
+ setOrDelValue(store, valueId, oldValue),
1378
+ );
1379
+ collClear(changedValues);
1380
+ }
1381
+ callListeners(finishTransactionListeners[0], void 0);
1382
+ transactions = -1;
1383
+ callInvalidCellListeners(0);
1384
+ if (!collIsEmpty(changedCells)) {
1385
+ callTabularListenersForChanges(0);
1386
+ }
1387
+ callInvalidValueListeners(0);
1388
+ if (!collIsEmpty(changedValues)) {
1389
+ callValuesListenersForChanges(0);
1390
+ }
1391
+ internalListeners[1]?.();
1392
+ callListeners(finishTransactionListeners[1], void 0);
1393
+ internalListeners[2]?.();
1394
+ transactions = 0;
1395
+ hadTables = hasTables();
1396
+ hadValues = hasValues();
1397
+ arrayForEach(
1398
+ [
1399
+ changedTableIds,
1400
+ changedTableCellIds,
1401
+ changedRowCount,
1402
+ changedRowIds,
1403
+ changedCellIds,
1404
+ changedCells,
1405
+ invalidCells,
1406
+ changedValueIds,
1407
+ changedValues,
1408
+ invalidValues,
1409
+ ],
1410
+ collClear,
1411
+ );
1412
+ }
1413
+ }
1414
+ return store;
1415
+ };
1416
+ const forEachTable = (tableCallback) =>
1417
+ collForEach(tablesMap, (tableMap, tableId) =>
1418
+ tableCallback(tableId, (rowCallback) =>
1419
+ collForEach(tableMap, (rowMap, rowId) =>
1420
+ rowCallback(rowId, (cellCallback) =>
1421
+ mapForEach(rowMap, cellCallback),
1422
+ ),
1423
+ ),
1424
+ ),
1425
+ );
1426
+ const forEachTableCell = (tableId, tableCellCallback) =>
1427
+ mapForEach(mapGet(tableCellIds, id(tableId)), tableCellCallback);
1428
+ const forEachRow = (tableId, rowCallback) =>
1429
+ collForEach(mapGet(tablesMap, id(tableId)), (rowMap, rowId) =>
1430
+ rowCallback(rowId, (cellCallback) => mapForEach(rowMap, cellCallback)),
1431
+ );
1432
+ const forEachCell = (tableId, rowId, cellCallback) =>
1433
+ mapForEach(mapGet(mapGet(tablesMap, id(tableId)), id(rowId)), cellCallback);
1434
+ const forEachValue = (valueCallback) => mapForEach(valuesMap, valueCallback);
1435
+ const addSortedRowIdsListener = (
1436
+ tableId,
1437
+ cellId,
1438
+ descending,
1439
+ offset,
1440
+ limit,
1441
+ listener,
1442
+ mutator,
1443
+ ) => {
1444
+ let sortedRowIds = getSortedRowIds(
1445
+ tableId,
1446
+ cellId,
1447
+ descending,
1448
+ offset,
1449
+ limit,
1450
+ );
1451
+ return addListener(
1452
+ () => {
1453
+ const newSortedRowIds = getSortedRowIds(
1454
+ tableId,
1455
+ cellId,
1456
+ descending,
1457
+ offset,
1458
+ limit,
1459
+ );
1460
+ if (!arrayIsEqual(newSortedRowIds, sortedRowIds)) {
1461
+ sortedRowIds = newSortedRowIds;
1462
+ listener(
1463
+ store,
1464
+ tableId,
1465
+ cellId,
1466
+ descending,
1467
+ offset,
1468
+ limit,
1469
+ sortedRowIds,
1470
+ );
1471
+ }
1472
+ },
1473
+ sortedRowIdsListeners[mutator ? 1 : 0],
1474
+ [tableId, cellId],
1475
+ [getTableIds],
1476
+ );
1477
+ };
1478
+ const addStartTransactionListener = (listener) =>
1479
+ addListener(listener, startTransactionListeners);
1480
+ const addWillFinishTransactionListener = (listener) =>
1481
+ addListener(listener, finishTransactionListeners[0]);
1482
+ const addDidFinishTransactionListener = (listener) =>
1483
+ addListener(listener, finishTransactionListeners[1]);
1484
+ const callListener = (listenerId) => {
1485
+ callListenerImpl(listenerId);
1486
+ return store;
1487
+ };
1488
+ const delListener = (listenerId) => {
1489
+ delListenerImpl(listenerId);
1490
+ return store;
1491
+ };
1492
+ const getListenerStats = () => ({
1493
+ hasTables: pairCollSize2(hasTablesListeners),
1494
+ tables: pairCollSize2(tablesListeners),
1495
+ tableIds: pairCollSize2(tableIdsListeners),
1496
+ hasTable: pairCollSize2(hasTableListeners),
1497
+ table: pairCollSize2(tableListeners),
1498
+ tableCellIds: pairCollSize2(tableCellIdsListeners),
1499
+ hasTableCell: pairCollSize2(hasTableCellListeners, collSize3),
1500
+ rowCount: pairCollSize2(rowCountListeners),
1501
+ rowIds: pairCollSize2(rowIdsListeners),
1502
+ sortedRowIds: pairCollSize2(sortedRowIdsListeners),
1503
+ hasRow: pairCollSize2(hasRowListeners, collSize3),
1504
+ row: pairCollSize2(rowListeners, collSize3),
1505
+ cellIds: pairCollSize2(cellIdsListeners, collSize3),
1506
+ hasCell: pairCollSize2(hasCellListeners, collSize4),
1507
+ cell: pairCollSize2(cellListeners, collSize4),
1508
+ invalidCell: pairCollSize2(invalidCellListeners, collSize4),
1509
+ hasValues: pairCollSize2(hasValuesListeners),
1510
+ values: pairCollSize2(valuesListeners),
1511
+ valueIds: pairCollSize2(valueIdsListeners),
1512
+ hasValue: pairCollSize2(hasValueListeners),
1513
+ value: pairCollSize2(valueListeners),
1514
+ invalidValue: pairCollSize2(invalidValueListeners),
1515
+ transaction:
1516
+ collSize2(startTransactionListeners) +
1517
+ pairCollSize2(finishTransactionListeners),
1518
+ });
1519
+ const setInternalListeners = (
1520
+ preStartTransaction,
1521
+ preFinishTransaction,
1522
+ postFinishTransaction,
1523
+ cellChanged2,
1524
+ valueChanged2,
1525
+ ) =>
1526
+ (internalListeners = [
1527
+ preStartTransaction,
1528
+ preFinishTransaction,
1529
+ postFinishTransaction,
1530
+ cellChanged2,
1531
+ valueChanged2,
1532
+ ]);
1533
+ const store = {
1534
+ getContent,
1535
+ getTables,
1536
+ getTableIds,
1537
+ getTable,
1538
+ getTableCellIds,
1539
+ getRowCount,
1540
+ getRowIds,
1541
+ getSortedRowIds,
1542
+ getRow,
1543
+ getCellIds,
1544
+ getCell,
1545
+ getValues,
1546
+ getValueIds,
1547
+ getValue,
1548
+ hasTables,
1549
+ hasTable,
1550
+ hasTableCell,
1551
+ hasRow,
1552
+ hasCell,
1553
+ hasValues,
1554
+ hasValue,
1555
+ getTablesJson,
1556
+ getValuesJson,
1557
+ getJson,
1558
+ getTablesSchemaJson,
1559
+ getValuesSchemaJson,
1560
+ getSchemaJson,
1561
+ hasTablesSchema: () => hasTablesSchema,
1562
+ hasValuesSchema: () => hasValuesSchema,
1563
+ setContent,
1564
+ setTables,
1565
+ setTable,
1566
+ setRow,
1567
+ addRow,
1568
+ setPartialRow,
1569
+ setCell,
1570
+ setValues,
1571
+ setPartialValues,
1572
+ setValue,
1573
+ applyChanges,
1574
+ setTablesJson,
1575
+ setValuesJson,
1576
+ setJson,
1577
+ setTablesSchema,
1578
+ setValuesSchema,
1579
+ setSchema,
1580
+ delTables,
1581
+ delTable,
1582
+ delRow,
1583
+ delCell,
1584
+ delValues,
1585
+ delValue,
1586
+ delTablesSchema,
1587
+ delValuesSchema,
1588
+ delSchema,
1589
+ transaction,
1590
+ startTransaction,
1591
+ getTransactionChanges,
1592
+ getTransactionLog,
1593
+ finishTransaction,
1594
+ forEachTable,
1595
+ forEachTableCell,
1596
+ forEachRow,
1597
+ forEachCell,
1598
+ forEachValue,
1599
+ addSortedRowIdsListener,
1600
+ addStartTransactionListener,
1601
+ addWillFinishTransactionListener,
1602
+ addDidFinishTransactionListener,
1603
+ callListener,
1604
+ delListener,
1605
+ getListenerStats,
1606
+ // only used internally by other modules
1607
+ createStore,
1608
+ addListener,
1609
+ callListeners,
1610
+ setInternalListeners,
1611
+ };
1612
+ objToArray(
1613
+ {
1614
+ [HAS + TABLES]: [0, hasTablesListeners, [], () => [hasTables()]],
1615
+ [TABLES]: [0, tablesListeners],
1616
+ [TABLE_IDS]: [0, tableIdsListeners],
1617
+ [HAS + TABLE]: [
1618
+ 1,
1619
+ hasTableListeners,
1620
+ [getTableIds],
1621
+ (ids) => [hasTable(...ids)],
1622
+ ],
1623
+ [TABLE]: [1, tableListeners, [getTableIds]],
1624
+ [TABLE + CELL_IDS]: [1, tableCellIdsListeners, [getTableIds]],
1625
+ [HAS + TABLE + CELL]: [
1626
+ 2,
1627
+ hasTableCellListeners,
1628
+ [getTableIds, getTableCellIds],
1629
+ (ids) => [hasTableCell(...ids)],
1630
+ ],
1631
+ [ROW_COUNT]: [1, rowCountListeners, [getTableIds]],
1632
+ [ROW_IDS]: [1, rowIdsListeners, [getTableIds]],
1633
+ [HAS + ROW]: [
1634
+ 2,
1635
+ hasRowListeners,
1636
+ [getTableIds, getRowIds],
1637
+ (ids) => [hasRow(...ids)],
1638
+ ],
1639
+ [ROW]: [2, rowListeners, [getTableIds, getRowIds]],
1640
+ [CELL_IDS]: [2, cellIdsListeners, [getTableIds, getRowIds]],
1641
+ [HAS + CELL]: [
1642
+ 3,
1643
+ hasCellListeners,
1644
+ [getTableIds, getRowIds, getCellIds],
1645
+ (ids) => [hasCell(...ids)],
1646
+ ],
1647
+ [CELL]: [
1648
+ 3,
1649
+ cellListeners,
1650
+ [getTableIds, getRowIds, getCellIds],
1651
+ (ids) => pairNew(getCell(...ids)),
1652
+ ],
1653
+ InvalidCell: [3, invalidCellListeners],
1654
+ [HAS + VALUES]: [0, hasValuesListeners, [], () => [hasValues()]],
1655
+ [VALUES]: [0, valuesListeners],
1656
+ [VALUE_IDS]: [0, valueIdsListeners],
1657
+ [HAS + VALUE]: [
1658
+ 1,
1659
+ hasValueListeners,
1660
+ [getValueIds],
1661
+ (ids) => [hasValue(...ids)],
1662
+ ],
1663
+ [VALUE]: [
1664
+ 1,
1665
+ valueListeners,
1666
+ [getValueIds],
1667
+ (ids) => pairNew(getValue(ids[0])),
1668
+ ],
1669
+ InvalidValue: [1, invalidValueListeners],
1670
+ },
1671
+ ([argumentCount, idSetNode, pathGetters, extraArgsGetter], listenable) => {
1672
+ store[ADD + listenable + LISTENER] = (...args) =>
1673
+ addListener(
1674
+ args[argumentCount],
1675
+ idSetNode[args[argumentCount + 1] ? 1 : 0],
1676
+ argumentCount > 0 ? slice(args, 0, argumentCount) : void 0,
1677
+ pathGetters,
1678
+ extraArgsGetter,
1679
+ );
1680
+ },
1681
+ );
1682
+ return objFreeze(store);
1683
+ };
1684
+
1685
+ const MASK6 = 63;
1686
+ const SHIFT36 = 2 ** 36;
1687
+ const SHIFT30 = 2 ** 30;
1688
+ const SHIFT24 = 2 ** 24;
1689
+ const SHIFT18 = 2 ** 18;
1690
+ const SHIFT12 = 2 ** 12;
1691
+ const SHIFT6 = 2 ** 6;
1692
+ const toB64 = (num) => String.fromCharCode(48 + (num & MASK6));
1693
+ const fromB64 = (str, pos) => strCharCodeAt(str, pos) - 48;
1694
+ const encodeHlc = (logicalTime42, counter24, clientHash30) =>
1695
+ toB64(logicalTime42 / SHIFT36) +
1696
+ toB64(logicalTime42 / SHIFT30) +
1697
+ toB64(logicalTime42 / SHIFT24) +
1698
+ toB64(logicalTime42 / SHIFT18) +
1699
+ toB64(logicalTime42 / SHIFT12) +
1700
+ toB64(logicalTime42 / SHIFT6) +
1701
+ toB64(logicalTime42) +
1702
+ toB64(counter24 / SHIFT18) +
1703
+ toB64(counter24 / SHIFT12) +
1704
+ toB64(counter24 / SHIFT6) +
1705
+ toB64(counter24) +
1706
+ toB64(clientHash30 / SHIFT24) +
1707
+ toB64(clientHash30 / SHIFT18) +
1708
+ toB64(clientHash30 / SHIFT12) +
1709
+ toB64(clientHash30 / SHIFT6) +
1710
+ toB64(clientHash30);
1711
+ const decodeHlc = (hlc16) => [
1712
+ fromB64(hlc16, 0) * SHIFT36 +
1713
+ fromB64(hlc16, 1) * SHIFT30 +
1714
+ fromB64(hlc16, 2) * SHIFT24 +
1715
+ fromB64(hlc16, 3) * SHIFT18 +
1716
+ fromB64(hlc16, 4) * SHIFT12 +
1717
+ fromB64(hlc16, 5) * SHIFT6 +
1718
+ fromB64(hlc16, 6),
1719
+ fromB64(hlc16, 7) * SHIFT18 +
1720
+ fromB64(hlc16, 8) * SHIFT12 +
1721
+ fromB64(hlc16, 9) * SHIFT6 +
1722
+ fromB64(hlc16, 10),
1723
+ fromB64(hlc16, 11) * SHIFT24 +
1724
+ fromB64(hlc16, 12) * SHIFT18 +
1725
+ fromB64(hlc16, 13) * SHIFT12 +
1726
+ fromB64(hlc16, 14) * SHIFT6 +
1727
+ fromB64(hlc16, 15),
1728
+ ];
1729
+ const getHlcFunctions = (uniqueId) => {
1730
+ let logicalTime = 0;
1731
+ let lastCounter = -1;
1732
+ const uniqueIdHash = getHash(uniqueId);
1733
+ const getHlc = () => {
1734
+ seenHlc();
1735
+ return encodeHlc(logicalTime, ++lastCounter, uniqueIdHash);
1736
+ };
1737
+ const seenHlc = (hlc) => {
1738
+ const previousLogicalTime = logicalTime;
1739
+ const [remoteLogicalTime, remoteCounter] =
1740
+ isUndefined(hlc) || hlc == '' ? [0, 0] : decodeHlc(hlc);
1741
+ logicalTime = mathMax(
1742
+ previousLogicalTime,
1743
+ remoteLogicalTime,
1744
+ globalThis.HLC_TIME ?? Date.now(),
1745
+ );
1746
+ lastCounter =
1747
+ logicalTime == previousLogicalTime
1748
+ ? logicalTime == remoteLogicalTime
1749
+ ? mathMax(lastCounter, remoteCounter)
1750
+ : lastCounter
1751
+ : logicalTime == remoteLogicalTime
1752
+ ? remoteCounter
1753
+ : -1;
1754
+ };
1755
+ return [getHlc, seenHlc];
1756
+ };
1757
+
1758
+ const LISTENER_ARGS = {
1759
+ HasTable: 1,
1760
+ Table: 1,
1761
+ TableCellIds: 1,
1762
+ HasTableCell: 2,
1763
+ RowCount: 1,
1764
+ RowIds: 1,
1765
+ SortedRowIds: 5,
1766
+ HasRow: 2,
1767
+ Row: 2,
1768
+ CellIds: 2,
1769
+ HasCell: 3,
1770
+ Cell: 3,
1771
+ HasValue: 1,
1772
+ Value: 1,
1773
+ InvalidCell: 3,
1774
+ InvalidValue: 1,
1775
+ };
1776
+ const newContentStampMap = (time = EMPTY_STRING) => [
1777
+ stampNewMap(time),
1778
+ stampNewMap(time),
1779
+ ];
1780
+ const validateMergeableContent = (mergeableContent) =>
1781
+ isArray(mergeableContent) &&
1782
+ size(mergeableContent) == 2 &&
1783
+ stampValidate(mergeableContent[0], (tableStamps) =>
1784
+ objValidate(
1785
+ tableStamps,
1786
+ (tableStamp) =>
1787
+ stampValidate(tableStamp, (rowStamps) =>
1788
+ objValidate(
1789
+ rowStamps,
1790
+ (rowStamp) =>
1791
+ stampValidate(rowStamp, (cellStamps) =>
1792
+ objValidate(
1793
+ cellStamps,
1794
+ (cellStamp) =>
1795
+ stampValidate(cellStamp, isCellOrValueOrNullOrUndefined),
1796
+ void 0,
1797
+ 1,
1798
+ ),
1799
+ ),
1800
+ void 0,
1801
+ 1,
1802
+ ),
1803
+ ),
1804
+ void 0,
1805
+ 1,
1806
+ ),
1807
+ ) &&
1808
+ stampValidate(mergeableContent[1], (values) =>
1809
+ objValidate(
1810
+ values,
1811
+ (value) => stampValidate(value, isCellOrValueOrNullOrUndefined),
1812
+ void 0,
1813
+ 1,
1814
+ ),
1815
+ );
1816
+ const createMergeableStore = (id) => {
1817
+ let listeningToRawStoreChanges = 1;
1818
+ let contentStampMap = newContentStampMap();
1819
+ let defaultingContent = 0;
1820
+ const touchedCells = mapNew();
1821
+ const touchedValues = setNew();
1822
+ const [getHlc, seenHlc] = getHlcFunctions(id);
1823
+ const store = createStore();
1824
+ const disableListeningToRawStoreChanges = (actions) => {
1825
+ const wasListening = listeningToRawStoreChanges;
1826
+ listeningToRawStoreChanges = 0;
1827
+ actions();
1828
+ listeningToRawStoreChanges = wasListening;
1829
+ return mergeableStore;
1830
+ };
1831
+ const mergeContentOrChanges = (contentOrChanges, isContent = 0) => {
1832
+ const tablesChanges = {};
1833
+ const valuesChanges = {};
1834
+ const [
1835
+ [tablesObj, incomingTablesTime = EMPTY_STRING, incomingTablesHash = 0],
1836
+ values,
1837
+ ] = contentOrChanges;
1838
+ const [tablesStampMap, valuesStampMap] = contentStampMap;
1839
+ const [tableStampMaps, oldTablesTime, oldTablesHash] = tablesStampMap;
1840
+ let tablesHash = isContent ? incomingTablesHash : oldTablesHash;
1841
+ let tablesTime = incomingTablesTime;
1842
+ objForEach(
1843
+ tablesObj,
1844
+ (
1845
+ [rowsObj, incomingTableTime = EMPTY_STRING, incomingTableHash = 0],
1846
+ tableId,
1847
+ ) => {
1848
+ const tableStampMap = mapEnsure(tableStampMaps, tableId, stampNewMap);
1849
+ const [rowStampMaps, oldTableTime, oldTableHash] = tableStampMap;
1850
+ let tableHash = isContent ? incomingTableHash : oldTableHash;
1851
+ let tableTime = incomingTableTime;
1852
+ objForEach(rowsObj, (row, rowId) => {
1853
+ const [rowTime, oldRowHash, rowHash] = mergeCellsOrValues(
1854
+ row,
1855
+ mapEnsure(rowStampMaps, rowId, stampNewMap),
1856
+ objEnsure(objEnsure(tablesChanges, tableId, objNew), rowId, objNew),
1857
+ isContent,
1858
+ );
1859
+ tableHash ^= isContent
1860
+ ? 0
1861
+ : (oldRowHash ? hashIdAndHash(rowId, oldRowHash) : 0) ^
1862
+ hashIdAndHash(rowId, rowHash);
1863
+ tableTime = getLatestTime(tableTime, rowTime);
1864
+ });
1865
+ tableHash ^= isContent
1866
+ ? 0
1867
+ : replaceTimeHash(oldTableTime, incomingTableTime);
1868
+ stampUpdate(tableStampMap, tableHash, incomingTableTime);
1869
+ tablesHash ^= isContent
1870
+ ? 0
1871
+ : (oldTableHash ? hashIdAndHash(tableId, oldTableHash) : 0) ^
1872
+ hashIdAndHash(tableId, tableStampMap[2]);
1873
+ tablesTime = getLatestTime(tablesTime, tableTime);
1874
+ },
1875
+ );
1876
+ tablesHash ^= isContent
1877
+ ? 0
1878
+ : replaceTimeHash(oldTablesTime, incomingTablesTime);
1879
+ stampUpdate(tablesStampMap, tablesHash, incomingTablesTime);
1880
+ const [valuesTime] = mergeCellsOrValues(
1881
+ values,
1882
+ valuesStampMap,
1883
+ valuesChanges,
1884
+ isContent,
1885
+ );
1886
+ seenHlc(getLatestTime(tablesTime, valuesTime));
1887
+ return [tablesChanges, valuesChanges, 1];
1888
+ };
1889
+ const mergeCellsOrValues = (
1890
+ things,
1891
+ thingsStampMap,
1892
+ thingsChanges,
1893
+ isContent,
1894
+ ) => {
1895
+ const [
1896
+ thingsObj,
1897
+ incomingThingsTime = EMPTY_STRING,
1898
+ incomingThingsHash = 0,
1899
+ ] = things;
1900
+ const [thingStampMaps, oldThingsTime, oldThingsHash] = thingsStampMap;
1901
+ let thingsTime = incomingThingsTime;
1902
+ let thingsHash = isContent ? incomingThingsHash : oldThingsHash;
1903
+ objForEach(
1904
+ thingsObj,
1905
+ ([thing, thingTime, incomingThingHash = 0], thingId) => {
1906
+ const thingStampMap = mapEnsure(thingStampMaps, thingId, () => [
1907
+ void 0,
1908
+ EMPTY_STRING,
1909
+ 0,
1910
+ ]);
1911
+ const [, oldThingTime, oldThingHash] = thingStampMap;
1912
+ if (!oldThingTime || thingTime > oldThingTime) {
1913
+ stampUpdate(
1914
+ thingStampMap,
1915
+ isContent
1916
+ ? incomingThingHash
1917
+ : getHash(jsonStringWithMap(thing ?? null) + ':' + thingTime),
1918
+ thingTime,
1919
+ );
1920
+ thingStampMap[0] = thing;
1921
+ thingsChanges[thingId] = thing;
1922
+ thingsHash ^= isContent
1923
+ ? 0
1924
+ : hashIdAndHash(thingId, oldThingHash) ^
1925
+ hashIdAndHash(thingId, thingStampMap[2]);
1926
+ thingsTime = getLatestTime(thingsTime, thingTime);
1927
+ }
1928
+ },
1929
+ );
1930
+ thingsHash ^= isContent
1931
+ ? 0
1932
+ : replaceTimeHash(oldThingsTime, incomingThingsTime);
1933
+ stampUpdate(thingsStampMap, thingsHash, incomingThingsTime);
1934
+ return [thingsTime, oldThingsHash, thingsStampMap[2]];
1935
+ };
1936
+ const preStartTransaction = () => {};
1937
+ const preFinishTransaction = () => {};
1938
+ const postFinishTransaction = () => {
1939
+ collClear(touchedCells);
1940
+ collClear(touchedValues);
1941
+ };
1942
+ const cellChanged = (tableId, rowId, cellId, newCell) => {
1943
+ setAdd(
1944
+ mapEnsure(mapEnsure(touchedCells, tableId, mapNew), rowId, setNew),
1945
+ cellId,
1946
+ );
1947
+ if (listeningToRawStoreChanges) {
1948
+ mergeContentOrChanges([
1949
+ [
1950
+ {
1951
+ [tableId]: [
1952
+ {
1953
+ [rowId]: [
1954
+ {
1955
+ [cellId]: [
1956
+ newCell,
1957
+ defaultingContent ? EMPTY_STRING : getHlc(),
1958
+ ],
1959
+ },
1960
+ ],
1961
+ },
1962
+ ],
1963
+ },
1964
+ ],
1965
+ [{}],
1966
+ 1,
1967
+ ]);
1968
+ }
1969
+ };
1970
+ const valueChanged = (valueId, newValue) => {
1971
+ setAdd(touchedValues, valueId);
1972
+ if (listeningToRawStoreChanges) {
1973
+ mergeContentOrChanges([
1974
+ [{}],
1975
+ [{[valueId]: [newValue, defaultingContent ? EMPTY_STRING : getHlc()]}],
1976
+ 1,
1977
+ ]);
1978
+ }
1979
+ };
1980
+ const getId = () => id;
1981
+ const getMergeableContent = () => [
1982
+ stampMapToObjWithHash(contentStampMap[0], (tableStampMap) =>
1983
+ stampMapToObjWithHash(tableStampMap, (rowStampMap) =>
1984
+ stampMapToObjWithHash(rowStampMap),
1985
+ ),
1986
+ ),
1987
+ stampMapToObjWithHash(contentStampMap[1]),
1988
+ ];
1989
+ const getMergeableContentHashes = () => [
1990
+ contentStampMap[0][2],
1991
+ contentStampMap[1][2],
1992
+ ];
1993
+ const getMergeableTableHashes = () =>
1994
+ mapToObj(contentStampMap[0][0], getStampHash);
1995
+ const getMergeableTableDiff = (otherTableHashes) => {
1996
+ const newTables = stampNewObj(contentStampMap[0][1]);
1997
+ const differentTableHashes = {};
1998
+ mapForEach(
1999
+ contentStampMap[0][0],
2000
+ (tableId, [tableStampMap, tableTime, hash]) =>
2001
+ objHas(otherTableHashes, tableId)
2002
+ ? hash != otherTableHashes[tableId]
2003
+ ? (differentTableHashes[tableId] = hash)
2004
+ : 0
2005
+ : (newTables[0][tableId] = stampMapToObjWithoutHash(
2006
+ [tableStampMap, tableTime],
2007
+ (rowStampMap) => stampMapToObjWithoutHash(rowStampMap),
2008
+ )),
2009
+ );
2010
+ return [newTables, differentTableHashes];
2011
+ };
2012
+ const getMergeableRowHashes = (otherTableHashes) => {
2013
+ const rowHashes = {};
2014
+ objForEach(otherTableHashes, (otherTableHash, tableId) =>
2015
+ ifNotUndefined(
2016
+ mapGet(contentStampMap[0][0], tableId),
2017
+ ([rowStampMaps, , tableHash]) =>
2018
+ tableHash != otherTableHash
2019
+ ? mapForEach(
2020
+ rowStampMaps,
2021
+ (rowId, [, , rowHash]) =>
2022
+ (objEnsure(rowHashes, tableId, objNew)[rowId] = rowHash),
2023
+ )
2024
+ : 0,
2025
+ ),
2026
+ );
2027
+ return rowHashes;
2028
+ };
2029
+ const getMergeableRowDiff = (otherTableRowHashes) => {
2030
+ const newRows = stampNewObj(contentStampMap[0][1]);
2031
+ const differentRowHashes = {};
2032
+ objForEach(otherTableRowHashes, (otherRowHashes, tableId) =>
2033
+ mapForEach(
2034
+ mapGet(contentStampMap[0][0], tableId)?.[0],
2035
+ (rowId, [rowStampMap, rowTime, hash]) =>
2036
+ objHas(otherRowHashes, rowId)
2037
+ ? hash !== otherRowHashes[rowId]
2038
+ ? (objEnsure(differentRowHashes, tableId, objNew)[rowId] = hash)
2039
+ : 0
2040
+ : (objEnsure(newRows[0], tableId, stampNewObj)[0][rowId] =
2041
+ stampMapToObjWithoutHash([rowStampMap, rowTime])),
2042
+ ),
2043
+ );
2044
+ return [newRows, differentRowHashes];
2045
+ };
2046
+ const getMergeableCellHashes = (otherTableRowHashes) => {
2047
+ const cellHashes = {};
2048
+ objForEach(otherTableRowHashes, (otherRowHashes, tableId) =>
2049
+ ifNotUndefined(mapGet(contentStampMap[0][0], tableId), ([rowStampMaps]) =>
2050
+ objForEach(otherRowHashes, (otherRowHash, rowId) =>
2051
+ ifNotUndefined(
2052
+ mapGet(rowStampMaps, rowId),
2053
+ ([cellStampMaps, , rowHash]) =>
2054
+ rowHash !== otherRowHash
2055
+ ? mapForEach(
2056
+ cellStampMaps,
2057
+ (cellId, [, , cellHash]) =>
2058
+ (objEnsure(
2059
+ objEnsure(cellHashes, tableId, objNew),
2060
+ rowId,
2061
+ objNew,
2062
+ )[cellId] = cellHash),
2063
+ )
2064
+ : 0,
2065
+ ),
2066
+ ),
2067
+ ),
2068
+ );
2069
+ return cellHashes;
2070
+ };
2071
+ const getMergeableCellDiff = (otherTableRowCellHashes) => {
2072
+ const [[tableStampMaps, tablesTime]] = contentStampMap;
2073
+ const tablesObj = {};
2074
+ objForEach(otherTableRowCellHashes, (otherRowCellHashes, tableId) =>
2075
+ objForEach(otherRowCellHashes, (otherCellHashes, rowId) =>
2076
+ ifNotUndefined(
2077
+ mapGet(tableStampMaps, tableId),
2078
+ ([rowStampMaps, tableTime]) =>
2079
+ ifNotUndefined(
2080
+ mapGet(rowStampMaps, rowId),
2081
+ ([cellStampMaps, rowTime]) =>
2082
+ mapForEach(cellStampMaps, (cellId, [cell, cellTime, hash]) =>
2083
+ hash !== otherCellHashes[cellId]
2084
+ ? (objEnsure(
2085
+ objEnsure(tablesObj, tableId, () =>
2086
+ stampNewObj(tableTime),
2087
+ )[0],
2088
+ rowId,
2089
+ () => stampNewObj(rowTime),
2090
+ )[0][cellId] = [cell, cellTime])
2091
+ : 0,
2092
+ ),
2093
+ ),
2094
+ ),
2095
+ ),
2096
+ );
2097
+ return newStamp(tablesObj, tablesTime);
2098
+ };
2099
+ const getMergeableValuesHashes = () =>
2100
+ mapToObj(contentStampMap[1][0], getStampHash);
2101
+ const getMergeableValueDiff = (relativeTo) => {
2102
+ const [, [valueStampMaps, valuesTime]] = contentStampMap;
2103
+ const values = mapToObj(
2104
+ valueStampMaps,
2105
+ stampCloneWithoutHash,
2106
+ ([, , hash], valueId) => hash == relativeTo?.[valueId],
2107
+ );
2108
+ return newStamp(values, valuesTime);
2109
+ };
2110
+ const setMergeableContent = (mergeableContent) =>
2111
+ disableListeningToRawStoreChanges(() =>
2112
+ validateMergeableContent(mergeableContent)
2113
+ ? store.transaction(() => {
2114
+ store.delTables().delValues();
2115
+ contentStampMap = newContentStampMap();
2116
+ store.applyChanges(mergeContentOrChanges(mergeableContent, 1));
2117
+ })
2118
+ : 0,
2119
+ );
2120
+ const setDefaultContent = (content) => {
2121
+ store.transaction(() => {
2122
+ defaultingContent = 1;
2123
+ store.setContent(content);
2124
+ defaultingContent = 0;
2125
+ });
2126
+ return mergeableStore;
2127
+ };
2128
+ const getTransactionMergeableChanges = () => {
2129
+ const [[tableStampMaps, tablesTime], [valueStampMaps, valuesTime]] =
2130
+ contentStampMap;
2131
+ const tablesObj = {};
2132
+ collForEach(touchedCells, (touchedTable, tableId) =>
2133
+ ifNotUndefined(
2134
+ mapGet(tableStampMaps, tableId),
2135
+ ([rowStampMaps, tableTime]) => {
2136
+ const tableObj = {};
2137
+ collForEach(touchedTable, (touchedRow, rowId) =>
2138
+ ifNotUndefined(
2139
+ mapGet(rowStampMaps, rowId),
2140
+ ([cellStampMaps, rowTime]) => {
2141
+ const rowObj = {};
2142
+ collForEach(touchedRow, (cellId) => {
2143
+ ifNotUndefined(
2144
+ mapGet(cellStampMaps, cellId),
2145
+ ([cell, time]) => (rowObj[cellId] = newStamp(cell, time)),
2146
+ );
2147
+ });
2148
+ tableObj[rowId] = newStamp(rowObj, rowTime);
2149
+ },
2150
+ ),
2151
+ );
2152
+ tablesObj[tableId] = newStamp(tableObj, tableTime);
2153
+ },
2154
+ ),
2155
+ );
2156
+ const valuesObj = {};
2157
+ collForEach(touchedValues, (valueId) =>
2158
+ ifNotUndefined(
2159
+ mapGet(valueStampMaps, valueId),
2160
+ ([value, time]) => (valuesObj[valueId] = newStamp(value, time)),
2161
+ ),
2162
+ );
2163
+ return [
2164
+ newStamp(tablesObj, tablesTime),
2165
+ newStamp(valuesObj, valuesTime),
2166
+ 1,
2167
+ ];
2168
+ };
2169
+ const applyMergeableChanges = (mergeableChanges) =>
2170
+ disableListeningToRawStoreChanges(() =>
2171
+ store.applyChanges(mergeContentOrChanges(mergeableChanges)),
2172
+ );
2173
+ const merge = (mergeableStore2) => {
2174
+ const mergeableChanges = getMergeableContent();
2175
+ const mergeableChanges2 = mergeableStore2.getMergeableContent();
2176
+ mergeableStore2.applyMergeableChanges(mergeableChanges);
2177
+ return applyMergeableChanges(mergeableChanges2);
2178
+ };
2179
+ const mergeableStore = {
2180
+ getId,
2181
+ getMergeableContent,
2182
+ getMergeableContentHashes,
2183
+ getMergeableTableHashes,
2184
+ getMergeableTableDiff,
2185
+ getMergeableRowHashes,
2186
+ getMergeableRowDiff,
2187
+ getMergeableCellHashes,
2188
+ getMergeableCellDiff,
2189
+ getMergeableValuesHashes,
2190
+ getMergeableValueDiff,
2191
+ setMergeableContent,
2192
+ setDefaultContent,
2193
+ getTransactionMergeableChanges,
2194
+ applyMergeableChanges,
2195
+ merge,
2196
+ };
2197
+ store.setInternalListeners(
2198
+ preStartTransaction,
2199
+ preFinishTransaction,
2200
+ postFinishTransaction,
2201
+ cellChanged,
2202
+ valueChanged,
2203
+ );
2204
+ objToArray(
2205
+ store,
2206
+ (method, name) =>
2207
+ (mergeableStore[name] = // fluent methods
2208
+ strStartsWith(name, 'set') ||
2209
+ strStartsWith(name, 'del') ||
2210
+ strStartsWith(name, 'apply') ||
2211
+ strEndsWith(name, 'Transaction') ||
2212
+ name == 'callListener'
2213
+ ? (...args) => {
2214
+ method(...args);
2215
+ return mergeableStore;
2216
+ }
2217
+ : strStartsWith(name, 'add') && strEndsWith(name, 'Listener')
2218
+ ? (...args) => {
2219
+ const listenerArg = LISTENER_ARGS[slice(name, 3, -8)] ?? 0;
2220
+ const listener = args[listenerArg];
2221
+ args[listenerArg] = (_store, ...args2) =>
2222
+ listener(mergeableStore, ...args2);
2223
+ return method(...args);
2224
+ }
2225
+ : method),
2226
+ );
2227
+ return objFreeze(mergeableStore);
2228
+ };
2229
+
2230
+ export {createMergeableStore};