tinybase 5.0.0-beta.2 → 5.0.0-beta.4

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 (274) hide show
  1. package/lib/cjs/mergeable-store.cjs +1 -1
  2. package/lib/cjs/mergeable-store.cjs.gz +0 -0
  3. package/lib/cjs/persisters/persister-automerge.cjs +1 -1
  4. package/lib/cjs/persisters/persister-automerge.cjs.gz +0 -0
  5. package/lib/cjs/persisters/persister-browser.cjs +1 -1
  6. package/lib/cjs/persisters/persister-browser.cjs.gz +0 -0
  7. package/lib/cjs/persisters/persister-cr-sqlite-wasm.cjs +1 -1
  8. package/lib/cjs/persisters/persister-cr-sqlite-wasm.cjs.gz +0 -0
  9. package/lib/cjs/persisters/persister-electric-sql.cjs +1 -1
  10. package/lib/cjs/persisters/persister-electric-sql.cjs.gz +0 -0
  11. package/lib/cjs/persisters/persister-expo-sqlite-next.cjs +1 -1
  12. package/lib/cjs/persisters/persister-expo-sqlite-next.cjs.gz +0 -0
  13. package/lib/cjs/persisters/persister-expo-sqlite.cjs +1 -1
  14. package/lib/cjs/persisters/persister-expo-sqlite.cjs.gz +0 -0
  15. package/lib/cjs/persisters/persister-file.cjs +1 -1
  16. package/lib/cjs/persisters/persister-file.cjs.gz +0 -0
  17. package/lib/cjs/persisters/persister-indexed-db.cjs +1 -1
  18. package/lib/cjs/persisters/persister-indexed-db.cjs.gz +0 -0
  19. package/lib/cjs/persisters/persister-partykit-client.cjs +1 -1
  20. package/lib/cjs/persisters/persister-partykit-client.cjs.gz +0 -0
  21. package/lib/cjs/persisters/persister-partykit-server.cjs +1 -1
  22. package/lib/cjs/persisters/persister-partykit-server.cjs.gz +0 -0
  23. package/lib/cjs/persisters/persister-remote.cjs +1 -1
  24. package/lib/cjs/persisters/persister-remote.cjs.gz +0 -0
  25. package/lib/cjs/persisters/persister-sqlite-wasm.cjs +1 -1
  26. package/lib/cjs/persisters/persister-sqlite-wasm.cjs.gz +0 -0
  27. package/lib/cjs/persisters/persister-sqlite3.cjs +1 -1
  28. package/lib/cjs/persisters/persister-sqlite3.cjs.gz +0 -0
  29. package/lib/cjs/persisters/persister-yjs.cjs +1 -1
  30. package/lib/cjs/persisters/persister-yjs.cjs.gz +0 -0
  31. package/lib/cjs/persisters.cjs +1 -1
  32. package/lib/cjs/persisters.cjs.gz +0 -0
  33. package/lib/cjs/store.cjs +1 -1
  34. package/lib/cjs/store.cjs.gz +0 -0
  35. package/lib/cjs/tinybase.cjs +1 -1
  36. package/lib/cjs/tinybase.cjs.gz +0 -0
  37. package/lib/cjs/tools.cjs +1 -1
  38. package/lib/cjs/tools.cjs.gz +0 -0
  39. package/lib/cjs/ui-react-dom-debug.cjs +1 -1
  40. package/lib/cjs/ui-react-dom-debug.cjs.gz +0 -0
  41. package/lib/cjs-es6/mergeable-store.cjs +1 -1
  42. package/lib/cjs-es6/mergeable-store.cjs.gz +0 -0
  43. package/lib/cjs-es6/persisters/persister-automerge.cjs +1 -1
  44. package/lib/cjs-es6/persisters/persister-automerge.cjs.gz +0 -0
  45. package/lib/cjs-es6/persisters/persister-browser.cjs +1 -1
  46. package/lib/cjs-es6/persisters/persister-browser.cjs.gz +0 -0
  47. package/lib/cjs-es6/persisters/persister-cr-sqlite-wasm.cjs +1 -1
  48. package/lib/cjs-es6/persisters/persister-cr-sqlite-wasm.cjs.gz +0 -0
  49. package/lib/cjs-es6/persisters/persister-electric-sql.cjs +1 -1
  50. package/lib/cjs-es6/persisters/persister-electric-sql.cjs.gz +0 -0
  51. package/lib/cjs-es6/persisters/persister-expo-sqlite-next.cjs +1 -1
  52. package/lib/cjs-es6/persisters/persister-expo-sqlite-next.cjs.gz +0 -0
  53. package/lib/cjs-es6/persisters/persister-expo-sqlite.cjs +1 -1
  54. package/lib/cjs-es6/persisters/persister-expo-sqlite.cjs.gz +0 -0
  55. package/lib/cjs-es6/persisters/persister-file.cjs +1 -1
  56. package/lib/cjs-es6/persisters/persister-file.cjs.gz +0 -0
  57. package/lib/cjs-es6/persisters/persister-indexed-db.cjs +1 -1
  58. package/lib/cjs-es6/persisters/persister-indexed-db.cjs.gz +0 -0
  59. package/lib/cjs-es6/persisters/persister-partykit-client.cjs +1 -1
  60. package/lib/cjs-es6/persisters/persister-partykit-client.cjs.gz +0 -0
  61. package/lib/cjs-es6/persisters/persister-partykit-server.cjs +1 -1
  62. package/lib/cjs-es6/persisters/persister-partykit-server.cjs.gz +0 -0
  63. package/lib/cjs-es6/persisters/persister-remote.cjs +1 -1
  64. package/lib/cjs-es6/persisters/persister-remote.cjs.gz +0 -0
  65. package/lib/cjs-es6/persisters/persister-sqlite-wasm.cjs +1 -1
  66. package/lib/cjs-es6/persisters/persister-sqlite-wasm.cjs.gz +0 -0
  67. package/lib/cjs-es6/persisters/persister-sqlite3.cjs +1 -1
  68. package/lib/cjs-es6/persisters/persister-sqlite3.cjs.gz +0 -0
  69. package/lib/cjs-es6/persisters/persister-yjs.cjs +1 -1
  70. package/lib/cjs-es6/persisters/persister-yjs.cjs.gz +0 -0
  71. package/lib/cjs-es6/persisters.cjs +1 -1
  72. package/lib/cjs-es6/persisters.cjs.gz +0 -0
  73. package/lib/cjs-es6/store.cjs +1 -1
  74. package/lib/cjs-es6/store.cjs.gz +0 -0
  75. package/lib/cjs-es6/tinybase.cjs +1 -1
  76. package/lib/cjs-es6/tinybase.cjs.gz +0 -0
  77. package/lib/cjs-es6/tools.cjs +1 -1
  78. package/lib/cjs-es6/tools.cjs.gz +0 -0
  79. package/lib/cjs-es6/ui-react-dom-debug.cjs +1 -1
  80. package/lib/cjs-es6/ui-react-dom-debug.cjs.gz +0 -0
  81. package/lib/debug/mergeable-store.js +223 -211
  82. package/lib/debug/persisters/persister-automerge.js +62 -41
  83. package/lib/debug/persisters/persister-browser.js +48 -16
  84. package/lib/debug/persisters/persister-cr-sqlite-wasm.js +97 -52
  85. package/lib/debug/persisters/persister-electric-sql.js +97 -52
  86. package/lib/debug/persisters/persister-expo-sqlite-next.js +97 -52
  87. package/lib/debug/persisters/persister-expo-sqlite.js +97 -52
  88. package/lib/debug/persisters/persister-file.js +47 -16
  89. package/lib/debug/persisters/persister-indexed-db.js +48 -18
  90. package/lib/debug/persisters/persister-partykit-client.js +46 -21
  91. package/lib/debug/persisters/persister-partykit-server.js +8 -18
  92. package/lib/debug/persisters/persister-remote.js +48 -16
  93. package/lib/debug/persisters/persister-sqlite-wasm.js +97 -52
  94. package/lib/debug/persisters/persister-sqlite3.js +97 -52
  95. package/lib/debug/persisters/persister-yjs.js +64 -40
  96. package/lib/debug/persisters.js +47 -16
  97. package/lib/debug/store.js +61 -83
  98. package/lib/debug/tinybase.js +264 -227
  99. package/lib/debug/tools.js +9 -11
  100. package/lib/debug/ui-react-dom.js +104 -99
  101. package/lib/es6/mergeable-store.js +1 -1
  102. package/lib/es6/mergeable-store.js.gz +0 -0
  103. package/lib/es6/persisters/persister-automerge.js +1 -1
  104. package/lib/es6/persisters/persister-automerge.js.gz +0 -0
  105. package/lib/es6/persisters/persister-browser.js +1 -1
  106. package/lib/es6/persisters/persister-browser.js.gz +0 -0
  107. package/lib/es6/persisters/persister-cr-sqlite-wasm.js +1 -1
  108. package/lib/es6/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
  109. package/lib/es6/persisters/persister-electric-sql.js +1 -1
  110. package/lib/es6/persisters/persister-electric-sql.js.gz +0 -0
  111. package/lib/es6/persisters/persister-expo-sqlite-next.js +1 -1
  112. package/lib/es6/persisters/persister-expo-sqlite-next.js.gz +0 -0
  113. package/lib/es6/persisters/persister-expo-sqlite.js +1 -1
  114. package/lib/es6/persisters/persister-expo-sqlite.js.gz +0 -0
  115. package/lib/es6/persisters/persister-file.js +1 -1
  116. package/lib/es6/persisters/persister-file.js.gz +0 -0
  117. package/lib/es6/persisters/persister-indexed-db.js +1 -1
  118. package/lib/es6/persisters/persister-indexed-db.js.gz +0 -0
  119. package/lib/es6/persisters/persister-partykit-client.js +1 -1
  120. package/lib/es6/persisters/persister-partykit-client.js.gz +0 -0
  121. package/lib/es6/persisters/persister-partykit-server.js +1 -1
  122. package/lib/es6/persisters/persister-partykit-server.js.gz +0 -0
  123. package/lib/es6/persisters/persister-remote.js +1 -1
  124. package/lib/es6/persisters/persister-remote.js.gz +0 -0
  125. package/lib/es6/persisters/persister-sqlite-wasm.js +1 -1
  126. package/lib/es6/persisters/persister-sqlite-wasm.js.gz +0 -0
  127. package/lib/es6/persisters/persister-sqlite3.js +1 -1
  128. package/lib/es6/persisters/persister-sqlite3.js.gz +0 -0
  129. package/lib/es6/persisters/persister-yjs.js +1 -1
  130. package/lib/es6/persisters/persister-yjs.js.gz +0 -0
  131. package/lib/es6/persisters.js +1 -1
  132. package/lib/es6/persisters.js.gz +0 -0
  133. package/lib/es6/store.js +1 -1
  134. package/lib/es6/store.js.gz +0 -0
  135. package/lib/es6/tinybase.js +1 -1
  136. package/lib/es6/tinybase.js.gz +0 -0
  137. package/lib/es6/tools.js +1 -1
  138. package/lib/es6/tools.js.gz +0 -0
  139. package/lib/es6/ui-react-dom-debug.js +1 -1
  140. package/lib/es6/ui-react-dom-debug.js.gz +0 -0
  141. package/lib/mergeable-store.js +1 -1
  142. package/lib/mergeable-store.js.gz +0 -0
  143. package/lib/persisters/persister-automerge.js +1 -1
  144. package/lib/persisters/persister-automerge.js.gz +0 -0
  145. package/lib/persisters/persister-browser.js +1 -1
  146. package/lib/persisters/persister-browser.js.gz +0 -0
  147. package/lib/persisters/persister-cr-sqlite-wasm.js +1 -1
  148. package/lib/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
  149. package/lib/persisters/persister-electric-sql.js +1 -1
  150. package/lib/persisters/persister-electric-sql.js.gz +0 -0
  151. package/lib/persisters/persister-expo-sqlite-next.js +1 -1
  152. package/lib/persisters/persister-expo-sqlite-next.js.gz +0 -0
  153. package/lib/persisters/persister-expo-sqlite.js +1 -1
  154. package/lib/persisters/persister-expo-sqlite.js.gz +0 -0
  155. package/lib/persisters/persister-file.js +1 -1
  156. package/lib/persisters/persister-file.js.gz +0 -0
  157. package/lib/persisters/persister-indexed-db.js +1 -1
  158. package/lib/persisters/persister-indexed-db.js.gz +0 -0
  159. package/lib/persisters/persister-partykit-client.js +1 -1
  160. package/lib/persisters/persister-partykit-client.js.gz +0 -0
  161. package/lib/persisters/persister-partykit-server.js +1 -1
  162. package/lib/persisters/persister-partykit-server.js.gz +0 -0
  163. package/lib/persisters/persister-remote.js +1 -1
  164. package/lib/persisters/persister-remote.js.gz +0 -0
  165. package/lib/persisters/persister-sqlite-wasm.js +1 -1
  166. package/lib/persisters/persister-sqlite-wasm.js.gz +0 -0
  167. package/lib/persisters/persister-sqlite3.js +1 -1
  168. package/lib/persisters/persister-sqlite3.js.gz +0 -0
  169. package/lib/persisters/persister-yjs.js +1 -1
  170. package/lib/persisters/persister-yjs.js.gz +0 -0
  171. package/lib/persisters.js +1 -1
  172. package/lib/persisters.js.gz +0 -0
  173. package/lib/store.js +1 -1
  174. package/lib/store.js.gz +0 -0
  175. package/lib/tinybase.js +1 -1
  176. package/lib/tinybase.js.gz +0 -0
  177. package/lib/tools.js +1 -1
  178. package/lib/tools.js.gz +0 -0
  179. package/lib/types/mergeable-store.d.ts +43 -13
  180. package/lib/types/persisters/persister-browser.d.ts +2 -2
  181. package/lib/types/persisters/persister-file.d.ts +1 -1
  182. package/lib/types/persisters/persister-partykit-server.d.ts +7 -8
  183. package/lib/types/persisters.d.ts +61 -30
  184. package/lib/types/store.d.ts +153 -111
  185. package/lib/types/tools.d.ts +2 -2
  186. package/lib/types/with-schemas/mergeable-store.d.ts +46 -13
  187. package/lib/types/with-schemas/persisters/persister-browser.d.ts +2 -2
  188. package/lib/types/with-schemas/persisters/persister-file.d.ts +1 -1
  189. package/lib/types/with-schemas/persisters/persister-partykit-server.d.ts +10 -11
  190. package/lib/types/with-schemas/persisters.d.ts +88 -45
  191. package/lib/types/with-schemas/store.d.ts +165 -136
  192. package/lib/types/with-schemas/tools.d.ts +2 -2
  193. package/lib/umd/mergeable-store.js +1 -1
  194. package/lib/umd/mergeable-store.js.gz +0 -0
  195. package/lib/umd/persisters/persister-automerge.js +1 -1
  196. package/lib/umd/persisters/persister-automerge.js.gz +0 -0
  197. package/lib/umd/persisters/persister-browser.js +1 -1
  198. package/lib/umd/persisters/persister-browser.js.gz +0 -0
  199. package/lib/umd/persisters/persister-cr-sqlite-wasm.js +1 -1
  200. package/lib/umd/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
  201. package/lib/umd/persisters/persister-electric-sql.js +1 -1
  202. package/lib/umd/persisters/persister-electric-sql.js.gz +0 -0
  203. package/lib/umd/persisters/persister-expo-sqlite-next.js +1 -1
  204. package/lib/umd/persisters/persister-expo-sqlite-next.js.gz +0 -0
  205. package/lib/umd/persisters/persister-expo-sqlite.js +1 -1
  206. package/lib/umd/persisters/persister-expo-sqlite.js.gz +0 -0
  207. package/lib/umd/persisters/persister-file.js +1 -1
  208. package/lib/umd/persisters/persister-file.js.gz +0 -0
  209. package/lib/umd/persisters/persister-indexed-db.js +1 -1
  210. package/lib/umd/persisters/persister-indexed-db.js.gz +0 -0
  211. package/lib/umd/persisters/persister-partykit-client.js +1 -1
  212. package/lib/umd/persisters/persister-partykit-client.js.gz +0 -0
  213. package/lib/umd/persisters/persister-partykit-server.js +1 -1
  214. package/lib/umd/persisters/persister-partykit-server.js.gz +0 -0
  215. package/lib/umd/persisters/persister-remote.js +1 -1
  216. package/lib/umd/persisters/persister-remote.js.gz +0 -0
  217. package/lib/umd/persisters/persister-sqlite-wasm.js +1 -1
  218. package/lib/umd/persisters/persister-sqlite-wasm.js.gz +0 -0
  219. package/lib/umd/persisters/persister-sqlite3.js +1 -1
  220. package/lib/umd/persisters/persister-sqlite3.js.gz +0 -0
  221. package/lib/umd/persisters/persister-yjs.js +1 -1
  222. package/lib/umd/persisters/persister-yjs.js.gz +0 -0
  223. package/lib/umd/persisters.js +1 -1
  224. package/lib/umd/persisters.js.gz +0 -0
  225. package/lib/umd/store.js +1 -1
  226. package/lib/umd/store.js.gz +0 -0
  227. package/lib/umd/tinybase.js +1 -1
  228. package/lib/umd/tinybase.js.gz +0 -0
  229. package/lib/umd/tools.js +1 -1
  230. package/lib/umd/tools.js.gz +0 -0
  231. package/lib/umd/ui-react-dom-debug.js +1 -1
  232. package/lib/umd/ui-react-dom-debug.js.gz +0 -0
  233. package/lib/umd-es6/mergeable-store.js +1 -1
  234. package/lib/umd-es6/mergeable-store.js.gz +0 -0
  235. package/lib/umd-es6/persisters/persister-automerge.js +1 -1
  236. package/lib/umd-es6/persisters/persister-automerge.js.gz +0 -0
  237. package/lib/umd-es6/persisters/persister-browser.js +1 -1
  238. package/lib/umd-es6/persisters/persister-browser.js.gz +0 -0
  239. package/lib/umd-es6/persisters/persister-cr-sqlite-wasm.js +1 -1
  240. package/lib/umd-es6/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
  241. package/lib/umd-es6/persisters/persister-electric-sql.js +1 -1
  242. package/lib/umd-es6/persisters/persister-electric-sql.js.gz +0 -0
  243. package/lib/umd-es6/persisters/persister-expo-sqlite-next.js +1 -1
  244. package/lib/umd-es6/persisters/persister-expo-sqlite-next.js.gz +0 -0
  245. package/lib/umd-es6/persisters/persister-expo-sqlite.js +1 -1
  246. package/lib/umd-es6/persisters/persister-expo-sqlite.js.gz +0 -0
  247. package/lib/umd-es6/persisters/persister-file.js +1 -1
  248. package/lib/umd-es6/persisters/persister-file.js.gz +0 -0
  249. package/lib/umd-es6/persisters/persister-indexed-db.js +1 -1
  250. package/lib/umd-es6/persisters/persister-indexed-db.js.gz +0 -0
  251. package/lib/umd-es6/persisters/persister-partykit-client.js +1 -1
  252. package/lib/umd-es6/persisters/persister-partykit-client.js.gz +0 -0
  253. package/lib/umd-es6/persisters/persister-partykit-server.js +1 -1
  254. package/lib/umd-es6/persisters/persister-partykit-server.js.gz +0 -0
  255. package/lib/umd-es6/persisters/persister-remote.js +1 -1
  256. package/lib/umd-es6/persisters/persister-remote.js.gz +0 -0
  257. package/lib/umd-es6/persisters/persister-sqlite-wasm.js +1 -1
  258. package/lib/umd-es6/persisters/persister-sqlite-wasm.js.gz +0 -0
  259. package/lib/umd-es6/persisters/persister-sqlite3.js +1 -1
  260. package/lib/umd-es6/persisters/persister-sqlite3.js.gz +0 -0
  261. package/lib/umd-es6/persisters/persister-yjs.js +1 -1
  262. package/lib/umd-es6/persisters/persister-yjs.js.gz +0 -0
  263. package/lib/umd-es6/persisters.js +1 -1
  264. package/lib/umd-es6/persisters.js.gz +0 -0
  265. package/lib/umd-es6/store.js +1 -1
  266. package/lib/umd-es6/store.js.gz +0 -0
  267. package/lib/umd-es6/tinybase.js +1 -1
  268. package/lib/umd-es6/tinybase.js.gz +0 -0
  269. package/lib/umd-es6/tools.js +1 -1
  270. package/lib/umd-es6/tools.js.gz +0 -0
  271. package/lib/umd-es6/ui-react-dom-debug.js +1 -1
  272. package/lib/umd-es6/ui-react-dom-debug.js.gz +0 -0
  273. package/package.json +29 -25
  274. package/readme.md +2 -2
@@ -88,8 +88,8 @@ const isObject = (obj) =>
88
88
  /* istanbul ignore next */
89
89
  () => true,
90
90
  );
91
- const objGet = (obj, id) => ifNotUndefined(obj, (obj2) => obj2[id]);
92
- const objHas = (obj, id) => !isUndefined(objGet(obj, id));
91
+ const objNew = (entries = []) => object.fromEntries(entries);
92
+ const objHas = (obj, id) => id in obj;
93
93
  const objDel = (obj, id) => {
94
94
  delete obj[id];
95
95
  return obj;
@@ -1085,6 +1085,23 @@ const createMetrics = getCreateFunction((store) => {
1085
1085
 
1086
1086
  const scheduleRunning = mapNew();
1087
1087
  const scheduleActions = mapNew();
1088
+ const isMergeable = (contentOrChanges) => isString(contentOrChanges?.[0]);
1089
+ const getStoreFunctions = (supportsMergeableStore, store) =>
1090
+ !supportsMergeableStore || isUndefined(store.getMergeableContent)
1091
+ ? [
1092
+ 0,
1093
+ store.getContent,
1094
+ store.getTransactionChanges,
1095
+ ([changedTables, changedValues]) =>
1096
+ !objIsEmpty(changedTables) || !objIsEmpty(changedValues),
1097
+ ]
1098
+ : [
1099
+ 1,
1100
+ store.getMergeableContent,
1101
+ store.getTransactionMergeableChanges,
1102
+ ([, [[, changedTables], [, changedValues]]]) =>
1103
+ !objIsEmpty(changedTables) || !objIsEmpty(changedValues),
1104
+ ];
1088
1105
  const createCustomPersister = (
1089
1106
  store,
1090
1107
  getPersisted,
@@ -1092,6 +1109,7 @@ const createCustomPersister = (
1092
1109
  addPersisterListener,
1093
1110
  delPersisterListener,
1094
1111
  onIgnoredError,
1112
+ supportsMergeableStore,
1095
1113
  [getThing, thing] = [],
1096
1114
  scheduleId = [],
1097
1115
  ) => {
@@ -1104,6 +1122,8 @@ const createCustomPersister = (
1104
1122
  let listeningHandle;
1105
1123
  mapEnsure(scheduleRunning, scheduleId, () => 0);
1106
1124
  mapEnsure(scheduleActions, scheduleId, () => []);
1125
+ const [isMergeableStore, getContent, getChanges, hasChanges] =
1126
+ getStoreFunctions(supportsMergeableStore, store);
1107
1127
  const run = async () => {
1108
1128
  /* istanbul ignore else */
1109
1129
  if (!mapGet(scheduleRunning, scheduleId)) {
@@ -1139,7 +1159,10 @@ const createCustomPersister = (
1139
1159
  load: async (initialTables, initialValues) =>
1140
1160
  await loadLock(async () => {
1141
1161
  try {
1142
- store.setContent(await getPersisted());
1162
+ const content = await getPersisted();
1163
+ (isMergeableStore && isMergeable(content)
1164
+ ? store.setMergeableContent
1165
+ : store.setContent)(content);
1143
1166
  } catch {
1144
1167
  store.setContent([initialTables, initialValues]);
1145
1168
  }
@@ -1149,16 +1172,21 @@ const createCustomPersister = (
1149
1172
  await persister.load(initialTables, initialValues);
1150
1173
  listening = 1;
1151
1174
  listeningHandle = addPersisterListener(
1152
- async (getContent, getTransactionChanges) => {
1153
- if (getTransactionChanges) {
1154
- const transactionChanges = getTransactionChanges();
1175
+ async (getContent2, getChanges2) => {
1176
+ if (getChanges2) {
1177
+ const changes = getChanges2();
1155
1178
  await loadLock(async () =>
1156
- store.setTransactionChanges(transactionChanges),
1179
+ (isMergeableStore && isMergeable(changes)
1180
+ ? store.applyMergeableChanges
1181
+ : store.applyChanges)(changes),
1157
1182
  );
1158
1183
  } else {
1159
1184
  await loadLock(async () => {
1160
1185
  try {
1161
- store.setContent(getContent?.() ?? (await getPersisted()));
1186
+ const content = getContent2?.() ?? (await getPersisted());
1187
+ (isMergeableStore && isMergeable(content)
1188
+ ? store.setMergeableContent
1189
+ : store.setContent)(content);
1162
1190
  } catch (error) {
1163
1191
  onIgnoredError?.(error);
1164
1192
  }
@@ -1176,7 +1204,7 @@ const createCustomPersister = (
1176
1204
  }
1177
1205
  return persister;
1178
1206
  },
1179
- save: async (getTransactionChanges) => {
1207
+ save: async (getChanges2) => {
1180
1208
  /* istanbul ignore else */
1181
1209
  if (loadSave != 1) {
1182
1210
  loadSave = 2;
@@ -1185,7 +1213,7 @@ const createCustomPersister = (
1185
1213
  }
1186
1214
  await persister.schedule(async () => {
1187
1215
  try {
1188
- await setPersisted(store.getContent, getTransactionChanges);
1216
+ await setPersisted(getContent, getChanges2);
1189
1217
  } catch (error) {
1190
1218
  /* istanbul ignore next */
1191
1219
  onIgnoredError?.(error);
@@ -1197,14 +1225,12 @@ const createCustomPersister = (
1197
1225
  },
1198
1226
  startAutoSave: async () => {
1199
1227
  await persister.stopAutoSave().save();
1200
- listenerId = store.addDidFinishTransactionListener(
1201
- (_store, getTransactionChanges) => {
1202
- const [tableChanges, valueChanges] = getTransactionChanges();
1203
- if (!objIsEmpty(tableChanges) || !objIsEmpty(valueChanges)) {
1204
- persister.save(() => [tableChanges, valueChanges]);
1205
- }
1206
- },
1207
- );
1228
+ listenerId = store.addDidFinishTransactionListener(() => {
1229
+ const changes = getChanges();
1230
+ if (hasChanges(changes)) {
1231
+ persister.save(() => changes);
1232
+ }
1233
+ });
1208
1234
  return persister;
1209
1235
  },
1210
1236
  stopAutoSave: () => {
@@ -1875,51 +1901,36 @@ const createRelationships = getCreateFunction((store) => {
1875
1901
  return objFreeze(relationships);
1876
1902
  });
1877
1903
 
1878
- const newStamped = () => [EMPTY_STRING, null];
1879
- const newStampedMap = () => [EMPTY_STRING, mapNew()];
1880
- const mapStampedMapToObj = (stampedMap, mapper) =>
1881
- mapStamped(stampedMap, (map, stamp) => [
1882
- stamp,
1883
- isUndefined(map) ? null : mapToObj(map, mapper),
1884
- ]);
1885
- const mapStamped = ([stamp, value], mapper) => mapper(value, stamp);
1886
- const mergeStamp = (
1887
- [newStamp, newThing],
1888
- currentStampedThing,
1889
- getNextCurrentThing,
1890
- ifNewer = 0,
1891
- ) => {
1892
- const isNewer = newStamp > currentStampedThing[0];
1893
- if ((!ifNewer && currentStampedThing[1] !== null) || isNewer) {
1894
- currentStampedThing[1] = getNextCurrentThing(
1895
- newThing,
1896
- currentStampedThing[1],
1897
- );
1898
- }
1899
- if (isNewer) {
1900
- currentStampedThing[0] = newStamp;
1901
- }
1902
- return currentStampedThing;
1903
- };
1904
- const mergeEachStamp = (thingStamps, allThingStamps, changes, forEachThing) => {
1905
- objForEach(thingStamps, (thingStamp, thingId) =>
1904
+ const stampNew = (time = EMPTY_STRING, thing) => [time, thing];
1905
+ const stampNewMap = (time = EMPTY_STRING) => stampNew(time, mapNew());
1906
+ const stampNewObj = (time) => stampNew(time, objNew());
1907
+ const mapStamp = ([time, value], mapper) => [time, mapper(value, time)];
1908
+ const cloneStamp = ([time, value]) => [time, value];
1909
+ const mapStampMapToObj = (stampedMap, mapper) =>
1910
+ mapStamp(stampedMap, (map) => mapToObj(map, mapper));
1911
+ const mergeStamps = (newThingStamps, thingStamps, changes, merge) =>
1912
+ objForEach(newThingStamps, (newThingStamp, thingId) =>
1906
1913
  mergeStamp(
1907
- thingStamp,
1908
- mapEnsure(allThingStamps, thingId, newStamped),
1909
- (newThing, currentThing) => {
1910
- if (!forEachThing || isUndefined(newThing)) {
1911
- return (changes[thingId] = newThing ?? null);
1912
- }
1913
- currentThing ??= mapNew();
1914
- changes[thingId] = {};
1915
- forEachThing(newThing, currentThing, thingId);
1916
- return currentThing;
1917
- },
1918
- forEachThing ? 0 : 1,
1914
+ newThingStamp,
1915
+ mapEnsure(thingStamps, thingId, stampNewMap),
1916
+ (changes[thingId] = objNew()),
1917
+ merge,
1919
1918
  ),
1920
1919
  );
1921
- return allThingStamps;
1920
+ const mergeStamp = ([newTime, newThing], thingStamp, changes, merge) => {
1921
+ if (newTime > thingStamp[0]) {
1922
+ thingStamp[0] = newTime;
1923
+ }
1924
+ merge(newThing, thingStamp[1], changes);
1922
1925
  };
1926
+ const mergeLeafStamps = (newLeafStamps, leafStamps, changes) =>
1927
+ objForEach(newLeafStamps, ([newTime, newLeaf], leafId) => {
1928
+ const leafStamp = mapEnsure(leafStamps, leafId, stampNew);
1929
+ if (newTime > leafStamp[0]) {
1930
+ leafStamp[0] = newTime;
1931
+ leafStamp[1] = changes[leafId] = newLeaf;
1932
+ }
1933
+ });
1923
1934
 
1924
1935
  const pairNew = (value) => [value, value];
1925
1936
  const pairCollSize2 = (pair, func = collSize2) => func(pair[0]) + func(pair[1]);
@@ -1954,12 +1965,10 @@ const idsChanged = (changedIds, id2, addedOrRemoved) =>
1954
1965
  const createStore = () => {
1955
1966
  let hasTablesSchema;
1956
1967
  let hasValuesSchema;
1957
- let cellsTouched = false;
1958
- let valuesTouched = false;
1959
1968
  let hadTables = false;
1960
1969
  let hadValues = false;
1961
1970
  let transactions = 0;
1962
- let postTransactionListener;
1971
+ let internalListeners = [];
1963
1972
  const changedTableIds = mapNew();
1964
1973
  const changedTableCellIds = mapNew();
1965
1974
  const changedRowCount = mapNew();
@@ -2601,44 +2610,6 @@ const createStore = () => {
2601
2610
  transaction(() => actions(...arrayMap(args, id)));
2602
2611
  return store;
2603
2612
  };
2604
- const getTransactionChanges = () => [
2605
- mapToObj(
2606
- changedCells,
2607
- (table, tableId) =>
2608
- mapGet(changedTableIds, tableId) === -1
2609
- ? null
2610
- : mapToObj(
2611
- table,
2612
- (row, rowId) =>
2613
- mapGet(mapGet(changedRowIds, tableId), rowId) === -1
2614
- ? null
2615
- : mapToObj(
2616
- row,
2617
- ([, newCell]) => newCell ?? null,
2618
- (_, changedCell) => pairIsEqual(changedCell),
2619
- ),
2620
- objIsEmpty,
2621
- ),
2622
- objIsEmpty,
2623
- ),
2624
- mapToObj(
2625
- changedValues,
2626
- ([, newValue]) => newValue ?? null,
2627
- (_, changedValue) => pairIsEqual(changedValue),
2628
- ),
2629
- ];
2630
- const getTransactionLog = () => ({
2631
- cellsTouched,
2632
- valuesTouched,
2633
- changedCells: mapToObj3(changedCells, pairClone, pairIsEqual),
2634
- invalidCells: mapToObj3(invalidCells),
2635
- changedValues: mapToObj(changedValues, pairClone, pairIsEqual),
2636
- invalidValues: mapToObj(invalidValues),
2637
- changedTableIds: mapToObj(changedTableIds),
2638
- changedRowIds: mapToObj2(changedRowIds),
2639
- changedCellIds: mapToObj3(changedCellIds),
2640
- changedValueIds: mapToObj(changedValueIds),
2641
- });
2642
2613
  const getContent = () => [getTables(), getValues()];
2643
2614
  const getTables = () => mapToObj3(tablesMap);
2644
2615
  const getTableIds = () => mapKeys(tablesMap);
@@ -2786,9 +2757,9 @@ const createStore = () => {
2786
2757
  ),
2787
2758
  valueId,
2788
2759
  );
2789
- const setTransactionChanges = (transactionChanges) =>
2760
+ const applyChanges = (changes) =>
2790
2761
  fluentTransaction(() => {
2791
- objToArray(transactionChanges[0], (table, tableId) =>
2762
+ objToArray(changes[0], (table, tableId) =>
2792
2763
  isUndefined(table)
2793
2764
  ? delTable(tableId)
2794
2765
  : objToArray(table, (row, rowId) =>
@@ -2799,7 +2770,7 @@ const createStore = () => {
2799
2770
  ),
2800
2771
  ),
2801
2772
  );
2802
- objToArray(transactionChanges[1], (value, valueId) =>
2773
+ objToArray(changes[1], (value, valueId) =>
2803
2774
  setOrDelValue(store, valueId, value),
2804
2775
  );
2805
2776
  });
@@ -2926,31 +2897,62 @@ const createStore = () => {
2926
2897
  transactions++;
2927
2898
  }
2928
2899
  if (transactions == 1) {
2929
- callListeners(
2930
- startTransactionListeners,
2931
- void 0,
2932
- getTransactionChanges,
2933
- getTransactionLog,
2934
- );
2900
+ callListeners(startTransactionListeners, void 0);
2935
2901
  }
2936
2902
  return store;
2937
2903
  };
2904
+ const getTransactionChanges = () => [
2905
+ mapToObj(
2906
+ changedCells,
2907
+ (table, tableId) =>
2908
+ mapGet(changedTableIds, tableId) === -1
2909
+ ? void 0
2910
+ : mapToObj(
2911
+ table,
2912
+ (row, rowId) =>
2913
+ mapGet(mapGet(changedRowIds, tableId), rowId) === -1
2914
+ ? void 0
2915
+ : mapToObj(
2916
+ row,
2917
+ ([, newCell]) => newCell,
2918
+ (_, changedCell) => pairIsEqual(changedCell),
2919
+ ),
2920
+ objIsEmpty,
2921
+ ),
2922
+ objIsEmpty,
2923
+ ),
2924
+ mapToObj(
2925
+ changedValues,
2926
+ ([, newValue]) => newValue,
2927
+ (_, changedValue) => pairIsEqual(changedValue),
2928
+ ),
2929
+ ];
2930
+ const getTransactionLog = () => [
2931
+ !collIsEmpty(changedCells),
2932
+ !collIsEmpty(changedValues),
2933
+ mapToObj3(changedCells, pairClone, pairIsEqual),
2934
+ mapToObj3(invalidCells),
2935
+ mapToObj(changedValues, pairClone, pairIsEqual),
2936
+ mapToObj(invalidValues),
2937
+ mapToObj(changedTableIds),
2938
+ mapToObj2(changedRowIds),
2939
+ mapToObj3(changedCellIds),
2940
+ mapToObj(changedValueIds),
2941
+ ];
2938
2942
  const finishTransaction = (doRollback) => {
2939
2943
  if (transactions > 0) {
2940
2944
  transactions--;
2941
2945
  if (transactions == 0) {
2942
- cellsTouched = !collIsEmpty(changedCells);
2943
- valuesTouched = !collIsEmpty(changedValues);
2944
2946
  transactions = 1;
2945
2947
  callInvalidCellListeners(1);
2946
- if (cellsTouched) {
2948
+ if (!collIsEmpty(changedCells)) {
2947
2949
  callTabularListenersForChanges(1);
2948
2950
  }
2949
2951
  callInvalidValueListeners(1);
2950
- if (valuesTouched) {
2952
+ if (!collIsEmpty(changedValues)) {
2951
2953
  callValuesListenersForChanges(1);
2952
2954
  }
2953
- if (doRollback?.(getTransactionChanges, getTransactionLog)) {
2955
+ if (doRollback?.(store)) {
2954
2956
  collForEach(changedCells, (table, tableId) =>
2955
2957
  collForEach(table, (row, rowId) =>
2956
2958
  collForEach(row, ([oldCell], cellId) =>
@@ -2958,39 +2960,26 @@ const createStore = () => {
2958
2960
  ),
2959
2961
  ),
2960
2962
  );
2963
+ collClear(changedCells);
2961
2964
  collForEach(changedValues, ([oldValue], valueId) =>
2962
2965
  setOrDelValue(store, valueId, oldValue),
2963
2966
  );
2964
- cellsTouched = valuesTouched = false;
2967
+ collClear(changedValues);
2965
2968
  }
2966
- callListeners(
2967
- finishTransactionListeners[0],
2968
- void 0,
2969
- getTransactionChanges,
2970
- getTransactionLog,
2971
- );
2969
+ callListeners(finishTransactionListeners[0], void 0);
2972
2970
  transactions = -1;
2973
2971
  callInvalidCellListeners(0);
2974
- if (cellsTouched) {
2972
+ if (!collIsEmpty(changedCells)) {
2975
2973
  callTabularListenersForChanges(0);
2976
2974
  }
2977
2975
  callInvalidValueListeners(0);
2978
- if (valuesTouched) {
2976
+ if (!collIsEmpty(changedValues)) {
2979
2977
  callValuesListenersForChanges(0);
2980
2978
  }
2981
- callListeners(
2982
- finishTransactionListeners[1],
2983
- void 0,
2984
- getTransactionChanges,
2985
- getTransactionLog,
2986
- );
2987
- postTransactionListener?.(
2988
- store,
2989
- getTransactionChanges,
2990
- getTransactionLog,
2991
- );
2979
+ internalListeners[0]?.(store);
2980
+ callListeners(finishTransactionListeners[1], void 0);
2981
+ internalListeners[1]?.(store);
2992
2982
  transactions = 0;
2993
- cellsTouched = valuesTouched = false;
2994
2983
  hadTables = hasTables();
2995
2984
  hadValues = hasValues();
2996
2985
  arrayForEach(
@@ -3115,9 +3104,8 @@ const createStore = () => {
3115
3104
  collSize2(startTransactionListeners) +
3116
3105
  pairCollSize2(finishTransactionListeners),
3117
3106
  });
3118
- const addPostTransactionListener = (listener) => {
3119
- postTransactionListener = listener;
3120
- };
3107
+ const setInternalListeners = (preFinishTransaction, postFinishTransaction) =>
3108
+ (internalListeners = [preFinishTransaction, postFinishTransaction]);
3121
3109
  const store = {
3122
3110
  getContent,
3123
3111
  getTables,
@@ -3158,7 +3146,7 @@ const createStore = () => {
3158
3146
  setValues,
3159
3147
  setPartialValues,
3160
3148
  setValue,
3161
- setTransactionChanges,
3149
+ applyChanges,
3162
3150
  setTablesJson,
3163
3151
  setValuesJson,
3164
3152
  setJson,
@@ -3176,6 +3164,8 @@ const createStore = () => {
3176
3164
  delSchema,
3177
3165
  transaction,
3178
3166
  startTransaction,
3167
+ getTransactionChanges,
3168
+ getTransactionLog,
3179
3169
  finishTransaction,
3180
3170
  forEachTable,
3181
3171
  forEachTableCell,
@@ -3193,7 +3183,7 @@ const createStore = () => {
3193
3183
  createStore,
3194
3184
  addListener,
3195
3185
  callListeners,
3196
- addPostTransactionListener,
3186
+ setInternalListeners,
3197
3187
  };
3198
3188
  objToArray(
3199
3189
  {
@@ -3320,23 +3310,23 @@ const decodeHlc = (hlc16) => [
3320
3310
  ];
3321
3311
  const getHlcFunctions = (uniqueId) => {
3322
3312
  let logicalTime = 0;
3323
- let counter = 0;
3313
+ let lastCounter = -1;
3324
3314
  const uniqueIdHash = hash(uniqueId);
3325
3315
  const getHlc = () => {
3326
3316
  seenHlc();
3327
- return encodeHlc(logicalTime, ++counter, uniqueIdHash);
3317
+ return encodeHlc(logicalTime, ++lastCounter, uniqueIdHash);
3328
3318
  };
3329
3319
  const seenHlc = (hlc) => {
3330
3320
  const previousLogicalTime = logicalTime;
3331
3321
  const [remoteLogicalTime, remoteCounter] = isUndefined(hlc)
3332
3322
  ? [0, 0]
3333
3323
  : decodeHlc(hlc);
3334
- logicalTime = Math.max(previousLogicalTime, remoteLogicalTime, Date.now());
3335
- counter =
3324
+ logicalTime = mathMax(previousLogicalTime, remoteLogicalTime, Date.now());
3325
+ lastCounter =
3336
3326
  logicalTime == previousLogicalTime
3337
3327
  ? logicalTime == remoteLogicalTime
3338
- ? Math.max(counter, remoteCounter)
3339
- : counter
3328
+ ? mathMax(lastCounter, remoteCounter)
3329
+ : lastCounter
3340
3330
  : logicalTime == remoteLogicalTime
3341
3331
  ? remoteCounter
3342
3332
  : -1;
@@ -3362,119 +3352,166 @@ const LISTENER_ARGS = {
3362
3352
  InvalidCell: 3,
3363
3353
  InvalidValue: 1,
3364
3354
  };
3355
+ const newContentStamp = (time = EMPTY_STRING) => [
3356
+ time,
3357
+ [stampNewMap(time), stampNewMap(time)],
3358
+ ];
3365
3359
  const createMergeableStore = (id) => {
3366
3360
  let listening = 1;
3361
+ let contentStamp = newContentStamp();
3362
+ let transactionTime;
3363
+ let finishTransactionMergeableChanges;
3367
3364
  const [getHlc, seenHlc] = getHlcFunctions(id);
3368
3365
  const store = createStore();
3369
- const allContentStamp = [EMPTY_STRING, [newStampedMap(), newStampedMap()]];
3370
- const postTransactionListener = (_, getTransactionChanges) => {
3366
+ const disableListening = (actions) => {
3367
+ const wasListening = listening;
3368
+ listening = 0;
3369
+ actions();
3370
+ listening = wasListening;
3371
+ };
3372
+ const preFinishTransaction = () => {
3371
3373
  if (listening) {
3372
- const stamp = getHlc();
3373
- const [tablesChanges, valuesChanges] = getTransactionChanges();
3374
- const [allTablesStamp, allValuesStamp] = allContentStamp[1];
3375
- allContentStamp[0] = stamp;
3376
- if (!objIsEmpty(tablesChanges)) {
3377
- allTablesStamp[0] = stamp;
3378
- objToArray(tablesChanges, (tableChanges, tableId) => {
3379
- const allTableStamp = mapEnsure(
3380
- allTablesStamp[1],
3381
- tableId,
3382
- newStamped,
3383
- );
3384
- allTableStamp[0] = stamp;
3385
- if (isUndefined(tableChanges)) {
3386
- allTableStamp[1] = null;
3387
- } else {
3388
- const allRowsStamp = (allTableStamp[1] ??= mapNew());
3389
- objToArray(tableChanges, (rowChanges, rowId) => {
3390
- const allRowStamp = mapEnsure(allRowsStamp, rowId, newStamped);
3391
- allRowStamp[0] = stamp;
3392
- if (isUndefined(rowChanges)) {
3393
- allRowStamp[1] = null;
3394
- } else {
3395
- const allCellStamps = (allRowStamp[1] ??= mapNew());
3396
- objToArray(rowChanges, (cellChanges, cellId) =>
3397
- mapSet(allCellStamps, cellId, [stamp, cellChanges]),
3398
- );
3399
- }
3400
- });
3401
- }
3402
- });
3374
+ finishTransactionMergeableChanges = getTransactionMergeableChanges();
3375
+ const [time, [changedTablesStamp, changedValuesStamp]] =
3376
+ finishTransactionMergeableChanges;
3377
+ const cellsTouched = !objIsEmpty(changedTablesStamp[1]);
3378
+ const valuesTouched = !objIsEmpty(changedValuesStamp[1]);
3379
+ const [, [tablesStamp, valuesStamp]] = contentStamp;
3380
+ if (cellsTouched || valuesTouched) {
3381
+ contentStamp[0] = time;
3403
3382
  }
3404
- if (!objIsEmpty(valuesChanges)) {
3405
- allValuesStamp[0] = stamp;
3406
- objToArray(valuesChanges, (valueChanges, valueId) => {
3407
- mapSet(allValuesStamp[1], valueId, [stamp, valueChanges]);
3383
+ if (cellsTouched) {
3384
+ tablesStamp[0] = time;
3385
+ objToArray(changedTablesStamp[1], ([, changedRowStamps], tableId) => {
3386
+ const tableStamp = mapEnsure(tablesStamp[1], tableId, stampNewMap);
3387
+ tableStamp[0] = time;
3388
+ objToArray(changedRowStamps, ([, changedCellStamps], rowId) => {
3389
+ const rowStamp = mapEnsure(tableStamp[1], rowId, stampNewMap);
3390
+ rowStamp[0] = time;
3391
+ objToArray(changedCellStamps, ([, newCell], cellId) =>
3392
+ mapSet(rowStamp[1], cellId, stampNew(time, newCell)),
3393
+ );
3394
+ });
3408
3395
  });
3409
3396
  }
3397
+ if (valuesTouched) {
3398
+ valuesStamp[0] = time;
3399
+ objToArray(changedValuesStamp[1], ([, newValue], valueId) =>
3400
+ mapSet(valuesStamp[1], valueId, stampNew(time, newValue)),
3401
+ );
3402
+ }
3410
3403
  }
3411
3404
  };
3405
+ const postFinishTransaction = () =>
3406
+ (transactionTime = finishTransactionMergeableChanges = void 0);
3412
3407
  const merge = (mergeableStore2) => {
3413
3408
  const mergeableContent = mergeableStore.getMergeableContent();
3414
3409
  const mergeableContent2 = mergeableStore2.getMergeableContent();
3415
- mergeableStore2.applyMergeableContent(mergeableContent);
3416
- return applyMergeableContent(mergeableContent2);
3410
+ mergeableStore2.applyMergeableChanges(mergeableContent);
3411
+ return applyMergeableChanges(mergeableContent2);
3417
3412
  };
3418
3413
  const getMergeableContent = () =>
3419
- mapStamped(allContentStamp, ([allTablesStamp, allValuesStamp], stamp) => [
3420
- stamp,
3421
- [
3422
- mapStampedMapToObj(allTablesStamp, (allRowStamp) =>
3423
- mapStampedMapToObj(allRowStamp, (allCellsStamp) =>
3424
- mapStampedMapToObj(allCellsStamp, pairClone),
3425
- ),
3414
+ mapStamp(contentStamp, ([tablesStamp, valuesStamp]) => [
3415
+ mapStampMapToObj(tablesStamp, (rowsStamp) =>
3416
+ mapStampMapToObj(rowsStamp, (cellsStamp) =>
3417
+ mapStampMapToObj(cellsStamp, cloneStamp),
3426
3418
  ),
3427
- mapStampedMapToObj(allValuesStamp, pairClone),
3428
- ],
3419
+ ),
3420
+ mapStampMapToObj(valuesStamp, cloneStamp),
3429
3421
  ]);
3430
- const applyMergeableContent = (mergeableContent) => {
3422
+ const setMergeableContent = (mergeableContent) => {
3423
+ disableListening(() =>
3424
+ store.transaction(() => {
3425
+ store.delTables().delValues();
3426
+ contentStamp = newContentStamp();
3427
+ }),
3428
+ );
3429
+ applyMergeableChanges(mergeableContent);
3430
+ return mergeableStore;
3431
+ };
3432
+ const getTransactionMergeableChanges = () => {
3433
+ if (isUndefined(finishTransactionMergeableChanges)) {
3434
+ const [, , changedCells, , changedValues] = store.getTransactionLog();
3435
+ const time =
3436
+ !objIsEmpty(changedCells) || !objIsEmpty(changedValues)
3437
+ ? transactionTime ?? (transactionTime = getHlc())
3438
+ : EMPTY_STRING;
3439
+ const mergeableChanges = stampNew(time, [
3440
+ stampNewObj(objIsEmpty(changedCells) ? EMPTY_STRING : time),
3441
+ stampNewObj(objIsEmpty(changedValues) ? EMPTY_STRING : time),
3442
+ ]);
3443
+ const [[, tableStamps], [, valuesStamp]] = mergeableChanges[1];
3444
+ objToArray(changedCells, (changedTable, tableId) => {
3445
+ const [, rowStamps] = (tableStamps[tableId] = stampNewObj(time));
3446
+ objToArray(changedTable, (changedRow, rowId) => {
3447
+ const [, cellStamps] = (rowStamps[rowId] = stampNewObj(time));
3448
+ objToArray(
3449
+ changedRow,
3450
+ ([, newCell], cellId) =>
3451
+ (cellStamps[cellId] = stampNew(time, newCell)),
3452
+ );
3453
+ });
3454
+ });
3455
+ objToArray(
3456
+ changedValues,
3457
+ ([, newValue], valueId) =>
3458
+ (valuesStamp[valueId] = stampNew(time, newValue)),
3459
+ );
3460
+ return mergeableChanges;
3461
+ }
3462
+ return finishTransactionMergeableChanges;
3463
+ };
3464
+ const applyMergeableChanges = (newContentStamp2) => {
3431
3465
  const changes = [{}, {}];
3432
- seenHlc(mergeableContent[0]);
3466
+ seenHlc(newContentStamp2[0]);
3433
3467
  mergeStamp(
3434
- mergeableContent,
3435
- allContentStamp,
3436
- ([tablesStamp, valuesStamp], [allTablesStamp, allValuesStamp]) => [
3437
- mergeStamp(tablesStamp, allTablesStamp, (tableStamps, allTableStamps) =>
3438
- mergeEachStamp(
3439
- tableStamps,
3440
- allTableStamps,
3441
- changes[0],
3442
- (rowStamps, allRowStamps, tableId) =>
3443
- mergeEachStamp(
3444
- rowStamps,
3445
- allRowStamps,
3446
- changes[0][tableId],
3447
- (cellStamps, allCellStamps, rowId) =>
3448
- mergeEachStamp(
3449
- cellStamps,
3450
- allCellStamps,
3451
- changes[0][tableId][rowId],
3452
- ),
3453
- ),
3454
- ),
3455
- ),
3456
- mergeStamp(valuesStamp, allValuesStamp, (valueStamps, allValueStamps) =>
3457
- mergeEachStamp(valueStamps, allValueStamps, changes[1]),
3458
- ),
3459
- ],
3468
+ newContentStamp2,
3469
+ contentStamp,
3470
+ changes,
3471
+ (
3472
+ [newTablesStamp, newValuesStamp],
3473
+ [tablesStamp, valuesStamp],
3474
+ [tablesChanges, valuesChanges],
3475
+ ) => {
3476
+ mergeStamp(
3477
+ newTablesStamp,
3478
+ tablesStamp,
3479
+ tablesChanges,
3480
+ (newTableStamps, tableStamps, tableChanges) =>
3481
+ mergeStamps(
3482
+ newTableStamps,
3483
+ tableStamps,
3484
+ tableChanges,
3485
+ (newRowStamps, rowStamps, rowChanges) =>
3486
+ mergeStamps(
3487
+ newRowStamps,
3488
+ rowStamps,
3489
+ rowChanges,
3490
+ mergeLeafStamps,
3491
+ ),
3492
+ ),
3493
+ );
3494
+ mergeStamp(newValuesStamp, valuesStamp, valuesChanges, mergeLeafStamps);
3495
+ },
3460
3496
  );
3461
- listening = 0;
3462
- store.setTransactionChanges(changes);
3463
- listening = 1;
3497
+ disableListening(() => store.applyChanges(changes));
3464
3498
  return mergeableStore;
3465
3499
  };
3466
3500
  const mergeableStore = {
3467
3501
  getMergeableContent,
3468
- applyMergeableContent,
3502
+ setMergeableContent,
3503
+ getTransactionMergeableChanges,
3504
+ applyMergeableChanges,
3469
3505
  merge,
3470
3506
  };
3471
- store.addPostTransactionListener(postTransactionListener);
3507
+ store.setInternalListeners(preFinishTransaction, postFinishTransaction);
3472
3508
  objToArray(
3473
3509
  store,
3474
3510
  (method, name) =>
3475
3511
  (mergeableStore[name] = // fluent methods
3476
3512
  strStartsWith(name, 'set') ||
3477
3513
  strStartsWith(name, 'del') ||
3514
+ strStartsWith(name, 'apply') ||
3478
3515
  strEndsWith(name, 'Transaction') ||
3479
3516
  name == 'callListener'
3480
3517
  ? (...args) => {