tinybase 7.3.3 → 7.3.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 (244) hide show
  1. package/checkpoints/index.js +12 -11
  2. package/checkpoints/with-schemas/index.js +12 -11
  3. package/common/index.js +3 -2
  4. package/common/with-schemas/index.js +3 -2
  5. package/index.js +92 -64
  6. package/indexes/index.js +13 -12
  7. package/indexes/with-schemas/index.js +13 -12
  8. package/mergeable-store/index.js +92 -64
  9. package/mergeable-store/with-schemas/index.js +92 -64
  10. package/metrics/index.js +13 -12
  11. package/metrics/with-schemas/index.js +13 -12
  12. package/min/checkpoints/index.js +1 -1
  13. package/min/checkpoints/index.js.gz +0 -0
  14. package/min/checkpoints/with-schemas/index.js +1 -1
  15. package/min/checkpoints/with-schemas/index.js.gz +0 -0
  16. package/min/common/index.js +1 -1
  17. package/min/common/index.js.gz +0 -0
  18. package/min/common/with-schemas/index.js +1 -1
  19. package/min/common/with-schemas/index.js.gz +0 -0
  20. package/min/index.js +1 -1
  21. package/min/index.js.gz +0 -0
  22. package/min/indexes/index.js +1 -1
  23. package/min/indexes/index.js.gz +0 -0
  24. package/min/indexes/with-schemas/index.js +1 -1
  25. package/min/indexes/with-schemas/index.js.gz +0 -0
  26. package/min/mergeable-store/index.js +1 -1
  27. package/min/mergeable-store/index.js.gz +0 -0
  28. package/min/mergeable-store/with-schemas/index.js +1 -1
  29. package/min/mergeable-store/with-schemas/index.js.gz +0 -0
  30. package/min/metrics/index.js +1 -1
  31. package/min/metrics/index.js.gz +0 -0
  32. package/min/metrics/with-schemas/index.js +1 -1
  33. package/min/metrics/with-schemas/index.js.gz +0 -0
  34. package/min/omni/index.js +1 -1
  35. package/min/omni/index.js.gz +0 -0
  36. package/min/omni/with-schemas/index.js +1 -1
  37. package/min/omni/with-schemas/index.js.gz +0 -0
  38. package/min/persisters/index.js +1 -1
  39. package/min/persisters/index.js.gz +0 -0
  40. package/min/persisters/persister-automerge/index.js +1 -1
  41. package/min/persisters/persister-automerge/index.js.gz +0 -0
  42. package/min/persisters/persister-automerge/with-schemas/index.js +1 -1
  43. package/min/persisters/persister-automerge/with-schemas/index.js.gz +0 -0
  44. package/min/persisters/persister-browser/index.js +1 -1
  45. package/min/persisters/persister-browser/index.js.gz +0 -0
  46. package/min/persisters/persister-browser/with-schemas/index.js +1 -1
  47. package/min/persisters/persister-browser/with-schemas/index.js.gz +0 -0
  48. package/min/persisters/persister-cr-sqlite-wasm/index.js +1 -1
  49. package/min/persisters/persister-cr-sqlite-wasm/index.js.gz +0 -0
  50. package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +1 -1
  51. package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js.gz +0 -0
  52. package/min/persisters/persister-durable-object-sql-storage/index.js +1 -1
  53. package/min/persisters/persister-durable-object-sql-storage/index.js.gz +0 -0
  54. package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js +1 -1
  55. package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js.gz +0 -0
  56. package/min/persisters/persister-durable-object-storage/index.js +1 -1
  57. package/min/persisters/persister-durable-object-storage/index.js.gz +0 -0
  58. package/min/persisters/persister-durable-object-storage/with-schemas/index.js +1 -1
  59. package/min/persisters/persister-durable-object-storage/with-schemas/index.js.gz +0 -0
  60. package/min/persisters/persister-electric-sql/index.js +1 -1
  61. package/min/persisters/persister-electric-sql/index.js.gz +0 -0
  62. package/min/persisters/persister-electric-sql/with-schemas/index.js +1 -1
  63. package/min/persisters/persister-electric-sql/with-schemas/index.js.gz +0 -0
  64. package/min/persisters/persister-expo-sqlite/index.js +1 -1
  65. package/min/persisters/persister-expo-sqlite/index.js.gz +0 -0
  66. package/min/persisters/persister-expo-sqlite/with-schemas/index.js +1 -1
  67. package/min/persisters/persister-expo-sqlite/with-schemas/index.js.gz +0 -0
  68. package/min/persisters/persister-file/index.js +1 -1
  69. package/min/persisters/persister-file/index.js.gz +0 -0
  70. package/min/persisters/persister-file/with-schemas/index.js +1 -1
  71. package/min/persisters/persister-file/with-schemas/index.js.gz +0 -0
  72. package/min/persisters/persister-indexed-db/index.js +1 -1
  73. package/min/persisters/persister-indexed-db/index.js.gz +0 -0
  74. package/min/persisters/persister-indexed-db/with-schemas/index.js +1 -1
  75. package/min/persisters/persister-indexed-db/with-schemas/index.js.gz +0 -0
  76. package/min/persisters/persister-libsql/index.js +1 -1
  77. package/min/persisters/persister-libsql/index.js.gz +0 -0
  78. package/min/persisters/persister-libsql/with-schemas/index.js +1 -1
  79. package/min/persisters/persister-libsql/with-schemas/index.js.gz +0 -0
  80. package/min/persisters/persister-partykit-client/index.js +1 -1
  81. package/min/persisters/persister-partykit-client/index.js.gz +0 -0
  82. package/min/persisters/persister-partykit-client/with-schemas/index.js +1 -1
  83. package/min/persisters/persister-partykit-client/with-schemas/index.js.gz +0 -0
  84. package/min/persisters/persister-pglite/index.js +1 -1
  85. package/min/persisters/persister-pglite/index.js.gz +0 -0
  86. package/min/persisters/persister-pglite/with-schemas/index.js +1 -1
  87. package/min/persisters/persister-pglite/with-schemas/index.js.gz +0 -0
  88. package/min/persisters/persister-postgres/index.js +1 -1
  89. package/min/persisters/persister-postgres/index.js.gz +0 -0
  90. package/min/persisters/persister-postgres/with-schemas/index.js +1 -1
  91. package/min/persisters/persister-postgres/with-schemas/index.js.gz +0 -0
  92. package/min/persisters/persister-powersync/index.js +1 -1
  93. package/min/persisters/persister-powersync/index.js.gz +0 -0
  94. package/min/persisters/persister-powersync/with-schemas/index.js +1 -1
  95. package/min/persisters/persister-powersync/with-schemas/index.js.gz +0 -0
  96. package/min/persisters/persister-react-native-mmkv/index.js +1 -1
  97. package/min/persisters/persister-react-native-mmkv/index.js.gz +0 -0
  98. package/min/persisters/persister-react-native-mmkv/with-schemas/index.js +1 -1
  99. package/min/persisters/persister-react-native-mmkv/with-schemas/index.js.gz +0 -0
  100. package/min/persisters/persister-react-native-sqlite/index.js +1 -1
  101. package/min/persisters/persister-react-native-sqlite/index.js.gz +0 -0
  102. package/min/persisters/persister-react-native-sqlite/with-schemas/index.js +1 -1
  103. package/min/persisters/persister-react-native-sqlite/with-schemas/index.js.gz +0 -0
  104. package/min/persisters/persister-remote/index.js +1 -1
  105. package/min/persisters/persister-remote/index.js.gz +0 -0
  106. package/min/persisters/persister-remote/with-schemas/index.js +1 -1
  107. package/min/persisters/persister-remote/with-schemas/index.js.gz +0 -0
  108. package/min/persisters/persister-sqlite-bun/index.js +1 -1
  109. package/min/persisters/persister-sqlite-bun/index.js.gz +0 -0
  110. package/min/persisters/persister-sqlite-bun/with-schemas/index.js +1 -1
  111. package/min/persisters/persister-sqlite-bun/with-schemas/index.js.gz +0 -0
  112. package/min/persisters/persister-sqlite-wasm/index.js +1 -1
  113. package/min/persisters/persister-sqlite-wasm/index.js.gz +0 -0
  114. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js +1 -1
  115. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js.gz +0 -0
  116. package/min/persisters/persister-sqlite3/index.js +1 -1
  117. package/min/persisters/persister-sqlite3/index.js.gz +0 -0
  118. package/min/persisters/persister-sqlite3/with-schemas/index.js +1 -1
  119. package/min/persisters/persister-sqlite3/with-schemas/index.js.gz +0 -0
  120. package/min/persisters/persister-yjs/index.js +1 -1
  121. package/min/persisters/persister-yjs/index.js.gz +0 -0
  122. package/min/persisters/persister-yjs/with-schemas/index.js +1 -1
  123. package/min/persisters/persister-yjs/with-schemas/index.js.gz +0 -0
  124. package/min/persisters/with-schemas/index.js +1 -1
  125. package/min/persisters/with-schemas/index.js.gz +0 -0
  126. package/min/queries/index.js +1 -1
  127. package/min/queries/index.js.gz +0 -0
  128. package/min/queries/with-schemas/index.js +1 -1
  129. package/min/queries/with-schemas/index.js.gz +0 -0
  130. package/min/relationships/index.js +1 -1
  131. package/min/relationships/index.js.gz +0 -0
  132. package/min/relationships/with-schemas/index.js +1 -1
  133. package/min/relationships/with-schemas/index.js.gz +0 -0
  134. package/min/store/index.js +1 -1
  135. package/min/store/index.js.gz +0 -0
  136. package/min/store/with-schemas/index.js +1 -1
  137. package/min/store/with-schemas/index.js.gz +0 -0
  138. package/min/synchronizers/index.js +1 -1
  139. package/min/synchronizers/index.js.gz +0 -0
  140. package/min/synchronizers/synchronizer-broadcast-channel/index.js +1 -1
  141. package/min/synchronizers/synchronizer-broadcast-channel/index.js.gz +0 -0
  142. package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +1 -1
  143. package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js.gz +0 -0
  144. package/min/synchronizers/synchronizer-local/index.js +1 -1
  145. package/min/synchronizers/synchronizer-local/index.js.gz +0 -0
  146. package/min/synchronizers/synchronizer-local/with-schemas/index.js +1 -1
  147. package/min/synchronizers/synchronizer-local/with-schemas/index.js.gz +0 -0
  148. package/min/synchronizers/synchronizer-ws-client/index.js +1 -1
  149. package/min/synchronizers/synchronizer-ws-client/index.js.gz +0 -0
  150. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js +1 -1
  151. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js.gz +0 -0
  152. package/min/synchronizers/synchronizer-ws-server/index.js +1 -1
  153. package/min/synchronizers/synchronizer-ws-server/index.js.gz +0 -0
  154. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js +1 -1
  155. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js.gz +0 -0
  156. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js +1 -1
  157. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js.gz +0 -0
  158. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +1 -1
  159. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js.gz +0 -0
  160. package/min/synchronizers/synchronizer-ws-server-simple/index.js +1 -1
  161. package/min/synchronizers/synchronizer-ws-server-simple/index.js.gz +0 -0
  162. package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +1 -1
  163. package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js.gz +0 -0
  164. package/min/synchronizers/with-schemas/index.js +1 -1
  165. package/min/synchronizers/with-schemas/index.js.gz +0 -0
  166. package/min/ui-react-inspector/index.js +1 -1
  167. package/min/ui-react-inspector/index.js.gz +0 -0
  168. package/min/ui-react-inspector/with-schemas/index.js +1 -1
  169. package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
  170. package/min/with-schemas/index.js +1 -1
  171. package/min/with-schemas/index.js.gz +0 -0
  172. package/omni/index.js +99 -64
  173. package/omni/with-schemas/index.js +99 -64
  174. package/package.json +3 -3
  175. package/persisters/index.js +19 -11
  176. package/persisters/persister-automerge/index.js +17 -9
  177. package/persisters/persister-automerge/with-schemas/index.js +17 -9
  178. package/persisters/persister-browser/index.js +17 -9
  179. package/persisters/persister-browser/with-schemas/index.js +17 -9
  180. package/persisters/persister-cr-sqlite-wasm/index.js +19 -11
  181. package/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +19 -11
  182. package/persisters/persister-durable-object-sql-storage/index.js +19 -11
  183. package/persisters/persister-durable-object-sql-storage/with-schemas/index.js +19 -11
  184. package/persisters/persister-durable-object-storage/index.js +19 -11
  185. package/persisters/persister-durable-object-storage/with-schemas/index.js +19 -11
  186. package/persisters/persister-electric-sql/index.js +19 -11
  187. package/persisters/persister-electric-sql/with-schemas/index.js +19 -11
  188. package/persisters/persister-expo-sqlite/index.js +19 -11
  189. package/persisters/persister-expo-sqlite/with-schemas/index.js +19 -11
  190. package/persisters/persister-file/index.js +17 -9
  191. package/persisters/persister-file/with-schemas/index.js +17 -9
  192. package/persisters/persister-indexed-db/index.js +17 -9
  193. package/persisters/persister-indexed-db/with-schemas/index.js +17 -9
  194. package/persisters/persister-libsql/index.js +19 -11
  195. package/persisters/persister-libsql/with-schemas/index.js +19 -11
  196. package/persisters/persister-partykit-client/index.js +17 -9
  197. package/persisters/persister-partykit-client/with-schemas/index.js +17 -9
  198. package/persisters/persister-partykit-server/index.js +2 -2
  199. package/persisters/persister-partykit-server/with-schemas/index.js +2 -2
  200. package/persisters/persister-pglite/index.js +19 -11
  201. package/persisters/persister-pglite/with-schemas/index.js +19 -11
  202. package/persisters/persister-postgres/index.js +19 -11
  203. package/persisters/persister-postgres/with-schemas/index.js +19 -11
  204. package/persisters/persister-powersync/index.js +19 -11
  205. package/persisters/persister-powersync/with-schemas/index.js +19 -11
  206. package/persisters/persister-react-native-mmkv/index.js +17 -9
  207. package/persisters/persister-react-native-mmkv/with-schemas/index.js +17 -9
  208. package/persisters/persister-react-native-sqlite/index.js +19 -11
  209. package/persisters/persister-react-native-sqlite/with-schemas/index.js +19 -11
  210. package/persisters/persister-remote/index.js +17 -9
  211. package/persisters/persister-remote/with-schemas/index.js +17 -9
  212. package/persisters/persister-sqlite-bun/index.js +19 -11
  213. package/persisters/persister-sqlite-bun/with-schemas/index.js +19 -11
  214. package/persisters/persister-sqlite-wasm/index.js +19 -11
  215. package/persisters/persister-sqlite-wasm/with-schemas/index.js +19 -11
  216. package/persisters/persister-sqlite3/index.js +19 -11
  217. package/persisters/persister-sqlite3/with-schemas/index.js +19 -11
  218. package/persisters/persister-yjs/index.js +19 -11
  219. package/persisters/persister-yjs/with-schemas/index.js +19 -11
  220. package/persisters/with-schemas/index.js +19 -11
  221. package/queries/index.js +15 -14
  222. package/queries/with-schemas/index.js +15 -14
  223. package/readme.md +2 -2
  224. package/relationships/index.js +13 -12
  225. package/relationships/with-schemas/index.js +13 -12
  226. package/store/index.js +74 -60
  227. package/store/with-schemas/index.js +74 -60
  228. package/synchronizers/index.js +17 -9
  229. package/synchronizers/synchronizer-broadcast-channel/index.js +17 -9
  230. package/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +17 -9
  231. package/synchronizers/synchronizer-local/index.js +19 -11
  232. package/synchronizers/synchronizer-local/with-schemas/index.js +19 -11
  233. package/synchronizers/synchronizer-ws-client/index.js +17 -9
  234. package/synchronizers/synchronizer-ws-client/with-schemas/index.js +17 -9
  235. package/synchronizers/synchronizer-ws-server/index.js +20 -12
  236. package/synchronizers/synchronizer-ws-server/with-schemas/index.js +20 -12
  237. package/synchronizers/synchronizer-ws-server-durable-object/index.js +17 -9
  238. package/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +17 -9
  239. package/synchronizers/synchronizer-ws-server-simple/index.js +11 -10
  240. package/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +11 -10
  241. package/synchronizers/with-schemas/index.js +17 -9
  242. package/ui-react-inspector/index.js +81 -60
  243. package/ui-react-inspector/with-schemas/index.js +81 -60
  244. package/with-schemas/index.js +92 -64
@@ -184,31 +184,32 @@ const getValueInValuesHash = (valueId, valueHash) =>
184
184
  const getValueHash = (value, valueHlc) =>
185
185
  getHash(jsonStringWithMap(value ?? null) + ':' + valueHlc);
186
186
 
187
- const mapNew = (entries) => new Map(entries);
188
- const mapKeys = (map) => [...(map?.keys() ?? [])];
189
- const mapGet = (map, key) => map?.get(key);
190
- const mapForEach = (map, cb) =>
191
- collForEach(map, (value, key) => cb(key, value));
187
+ const map = Map;
188
+ const mapNew = (entries) => new map(entries);
189
+ const mapKeys = (map2) => [...(map2?.keys() ?? [])];
190
+ const mapGet = (map2, key) => map2?.get(key);
191
+ const mapForEach = (map2, cb) =>
192
+ collForEach(map2, (value, key) => cb(key, value));
192
193
  const mapMap = (coll, cb) =>
193
194
  arrayMap([...(coll?.entries() ?? [])], ([key, value]) => cb(value, key));
194
- const mapSet = (map, key, value) =>
195
- isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
196
- const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
197
- if (!collHas(map, key)) {
198
- mapSet(map, key, getDefaultValue());
195
+ const mapSet = (map2, key, value) =>
196
+ isUndefined(value) ? (collDel(map2, key), map2) : map2?.set(key, value);
197
+ const mapEnsure = (map2, key, getDefaultValue, hadExistingValue) => {
198
+ if (!collHas(map2, key)) {
199
+ mapSet(map2, key, getDefaultValue());
199
200
  } else {
200
- hadExistingValue?.(mapGet(map, key));
201
+ hadExistingValue?.(mapGet(map2, key));
201
202
  }
202
- return mapGet(map, key);
203
+ return mapGet(map2, key);
203
204
  };
204
- const mapMatch = (map, obj, set, del = mapSet) => {
205
- objMap(obj, (value, id) => set(map, id, value));
206
- mapForEach(map, (id) => (objHas(obj, id) ? 0 : del(map, id)));
207
- return map;
205
+ const mapMatch = (map2, obj, set, del = mapSet) => {
206
+ objMap(obj, (value, id) => set(map2, id, value));
207
+ mapForEach(map2, (id) => (objHas(obj, id) ? 0 : del(map2, id)));
208
+ return map2;
208
209
  };
209
- const mapToObj = (map, valueMapper, excludeMapValue, excludeObjValue) => {
210
+ const mapToObj = (map2, valueMapper, excludeMapValue, excludeObjValue) => {
210
211
  const obj = {};
211
- collForEach(map, (mapValue, id) => {
212
+ collForEach(map2, (mapValue, id) => {
212
213
  if (!excludeMapValue?.(mapValue, id)) {
213
214
  const objValue = valueMapper ? valueMapper(mapValue, id) : mapValue;
214
215
  if (!excludeObjValue?.(objValue)) {
@@ -218,27 +219,27 @@ const mapToObj = (map, valueMapper, excludeMapValue, excludeObjValue) => {
218
219
  });
219
220
  return obj;
220
221
  };
221
- const mapToObj2 = (map, valueMapper, excludeMapValue) =>
222
+ const mapToObj2 = (map2, valueMapper, excludeMapValue) =>
222
223
  mapToObj(
223
- map,
224
+ map2,
224
225
  (childMap) => mapToObj(childMap, valueMapper, excludeMapValue),
225
226
  collIsEmpty,
226
227
  objIsEmpty,
227
228
  );
228
- const mapToObj3 = (map, valueMapper, excludeMapValue) =>
229
+ const mapToObj3 = (map2, valueMapper, excludeMapValue) =>
229
230
  mapToObj(
230
- map,
231
+ map2,
231
232
  (childMap) => mapToObj2(childMap, valueMapper, excludeMapValue),
232
233
  collIsEmpty,
233
234
  objIsEmpty,
234
235
  );
235
- const mapClone = (map, mapValue) => {
236
- const map2 = mapNew();
237
- collForEach(map, (value, key) => map2.set(key, mapValue?.(value) ?? value));
238
- return map2;
236
+ const mapClone = (map2, mapValue) => {
237
+ const map22 = mapNew();
238
+ collForEach(map2, (value, key) => map22.set(key, mapValue?.(value) ?? value));
239
+ return map22;
239
240
  };
240
- const mapClone2 = (map) => mapClone(map, mapClone);
241
- const mapClone3 = (map) => mapClone(map, mapClone2);
241
+ const mapClone2 = (map2) => mapClone(map2, mapClone);
242
+ const mapClone3 = (map2) => mapClone(map2, mapClone2);
242
243
  const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
243
244
  ifNotUndefined(
244
245
  (ensureLeaf ? mapEnsure : mapGet)(
@@ -510,6 +511,7 @@ const createStore = () => {
510
511
  let hadValues = false;
511
512
  let transactions = 0;
512
513
  let internalListeners = [];
514
+ let mutating = 0;
513
515
  const changedTableIds = mapNew();
514
516
  const changedTableCellIds = mapNew();
515
517
  const changedRowCount = mapNew();
@@ -914,13 +916,13 @@ const createStore = () => {
914
916
  cellId,
915
917
  () => [oldCell, 0],
916
918
  )[1] = newCell;
917
- internalListeners[3]?.(tableId, rowId, cellId, newCell);
919
+ internalListeners[3]?.(tableId, rowId, cellId, newCell, mutating);
918
920
  };
919
921
  const valueIdsChanged = (valueId, addedOrRemoved) =>
920
922
  idsChanged(changedValueIds, valueId, addedOrRemoved);
921
923
  const valueChanged = (valueId, oldValue, newValue) => {
922
924
  mapEnsure(changedValues, valueId, () => [oldValue, 0])[1] = newValue;
923
- internalListeners[4]?.(valueId, newValue);
925
+ internalListeners[4]?.(valueId, newValue, mutating);
924
926
  };
925
927
  const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
926
928
  arrayPush(
@@ -995,14 +997,11 @@ const createStore = () => {
995
997
  }
996
998
  };
997
999
  const callTabularListenersForChanges = (mutator) => {
998
- const hasTablesNow = hasTables();
999
- if (hasTablesNow != hadTables) {
1000
- callListeners(hasTablesListeners[mutator], void 0, hasTablesNow);
1001
- }
1002
- const emptySortedRowIdListeners = collIsEmpty(
1000
+ const hasHasTablesListeners = !collIsEmpty(hasTablesListeners[mutator]);
1001
+ const hasSortedRowIdListeners = !collIsEmpty(
1003
1002
  sortedRowIdsListeners[mutator],
1004
1003
  );
1005
- const emptyIdAndHasListeners =
1004
+ const hasIdOrHasListeners = !(
1006
1005
  collIsEmpty(cellIdsListeners[mutator]) &&
1007
1006
  collIsEmpty(hasCellListeners[mutator]) &&
1008
1007
  collIsEmpty(rowIdsListeners[mutator]) &&
@@ -1010,15 +1009,17 @@ const createStore = () => {
1010
1009
  collIsEmpty(tableCellIdsListeners[mutator]) &&
1011
1010
  collIsEmpty(hasTableCellListeners[mutator]) &&
1012
1011
  collIsEmpty(rowCountListeners[mutator]) &&
1013
- emptySortedRowIdListeners &&
1012
+ !hasSortedRowIdListeners &&
1014
1013
  collIsEmpty(tableIdsListeners[mutator]) &&
1015
- collIsEmpty(hasTableListeners[mutator]);
1016
- const emptyOtherListeners =
1014
+ collIsEmpty(hasTableListeners[mutator])
1015
+ );
1016
+ const hasOtherListeners = !(
1017
1017
  collIsEmpty(cellListeners[mutator]) &&
1018
1018
  collIsEmpty(rowListeners[mutator]) &&
1019
1019
  collIsEmpty(tableListeners[mutator]) &&
1020
- collIsEmpty(tablesListeners[mutator]);
1021
- if (!emptyIdAndHasListeners || !emptyOtherListeners) {
1020
+ collIsEmpty(tablesListeners[mutator])
1021
+ );
1022
+ if (hasHasTablesListeners || hasIdOrHasListeners || hasOtherListeners) {
1022
1023
  const changes = mutator
1023
1024
  ? [
1024
1025
  mapClone(changedTableIds),
@@ -1026,7 +1027,9 @@ const createStore = () => {
1026
1027
  mapClone(changedRowCount),
1027
1028
  mapClone2(changedRowIds),
1028
1029
  mapClone3(changedCellIds),
1029
- mapClone3(changedCells),
1030
+ mapClone(changedCells, (map) =>
1031
+ mapClone(map, (map2) => mapClone(map2, pairClone)),
1032
+ ),
1030
1033
  ]
1031
1034
  : [
1032
1035
  changedTableIds,
@@ -1036,7 +1039,13 @@ const createStore = () => {
1036
1039
  changedCellIds,
1037
1040
  changedCells,
1038
1041
  ];
1039
- if (!emptyIdAndHasListeners) {
1042
+ if (hasHasTablesListeners) {
1043
+ const hasTablesNow = hasTables();
1044
+ if (hasTablesNow != hadTables) {
1045
+ callListeners(hasTablesListeners[mutator], void 0, hasTablesNow);
1046
+ }
1047
+ }
1048
+ if (hasIdOrHasListeners) {
1040
1049
  callIdsAndHasListenersIfChanged(
1041
1050
  changes[0],
1042
1051
  tableIdsListeners[mutator],
@@ -1068,13 +1077,13 @@ const createStore = () => {
1068
1077
  hasRowListeners[mutator],
1069
1078
  [tableId],
1070
1079
  ) &&
1071
- !emptySortedRowIdListeners
1080
+ hasSortedRowIdListeners
1072
1081
  ) {
1073
1082
  callListeners(sortedRowIdsListeners[mutator], [tableId, null]);
1074
1083
  setAdd(calledSortableTableIds, tableId);
1075
1084
  }
1076
1085
  });
1077
- if (!emptySortedRowIdListeners) {
1086
+ if (hasSortedRowIdListeners) {
1078
1087
  collForEach(changes[5], (rows, tableId) => {
1079
1088
  if (!collHas(calledSortableTableIds, tableId)) {
1080
1089
  const sortableCellIds = setNew();
@@ -1105,7 +1114,7 @@ const createStore = () => {
1105
1114
  ),
1106
1115
  );
1107
1116
  }
1108
- if (!emptyOtherListeners) {
1117
+ if (hasOtherListeners) {
1109
1118
  let tablesChanged;
1110
1119
  collForEach(changes[5], (rows, tableId) => {
1111
1120
  let tableChanged;
@@ -1142,28 +1151,31 @@ const createStore = () => {
1142
1151
  }
1143
1152
  };
1144
1153
  const callValuesListenersForChanges = (mutator) => {
1145
- const hasValuesNow = hasValues();
1146
- if (hasValuesNow != hadValues) {
1147
- callListeners(hasValuesListeners[mutator], void 0, hasValuesNow);
1148
- }
1149
- const emptyIdAndHasListeners =
1150
- collIsEmpty(valueIdsListeners[mutator]) &&
1151
- collIsEmpty(hasValueListeners[mutator]);
1152
- const emptyOtherListeners =
1153
- collIsEmpty(valueListeners[mutator]) &&
1154
- collIsEmpty(valuesListeners[mutator]);
1155
- if (!emptyIdAndHasListeners || !emptyOtherListeners) {
1154
+ const hasHasValuesListeners = !collIsEmpty(hasValuesListeners[mutator]);
1155
+ const hasIdOrHasListeners =
1156
+ !collIsEmpty(valueIdsListeners[mutator]) ||
1157
+ !collIsEmpty(hasValueListeners[mutator]);
1158
+ const hasOtherListeners =
1159
+ !collIsEmpty(valueListeners[mutator]) ||
1160
+ !collIsEmpty(valuesListeners[mutator]);
1161
+ if (hasHasValuesListeners || hasIdOrHasListeners || hasOtherListeners) {
1156
1162
  const changes = mutator
1157
- ? [mapClone(changedValueIds), mapClone(changedValues)]
1163
+ ? [mapClone(changedValueIds), mapClone(changedValues, pairClone)]
1158
1164
  : [changedValueIds, changedValues];
1159
- if (!emptyIdAndHasListeners) {
1165
+ if (hasHasValuesListeners) {
1166
+ const hasValuesNow = hasValues();
1167
+ if (hasValuesNow != hadValues) {
1168
+ callListeners(hasValuesListeners[mutator], void 0, hasValuesNow);
1169
+ }
1170
+ }
1171
+ if (hasIdOrHasListeners) {
1160
1172
  callIdsAndHasListenersIfChanged(
1161
1173
  changes[0],
1162
1174
  valueIdsListeners[mutator],
1163
1175
  hasValueListeners[mutator],
1164
1176
  );
1165
1177
  }
1166
- if (!emptyOtherListeners) {
1178
+ if (hasOtherListeners) {
1167
1179
  let valuesChanged;
1168
1180
  collForEach(changes[1], ([oldValue, newValue], valueId) => {
1169
1181
  if (newValue !== oldValue) {
@@ -1560,6 +1572,7 @@ const createStore = () => {
1560
1572
  transactions--;
1561
1573
  if (transactions == 0) {
1562
1574
  transactions = 1;
1575
+ mutating = 1;
1563
1576
  callInvalidCellListeners(1);
1564
1577
  if (!collIsEmpty(changedCells)) {
1565
1578
  callTabularListenersForChanges(1);
@@ -1568,6 +1581,7 @@ const createStore = () => {
1568
1581
  if (!collIsEmpty(changedValues)) {
1569
1582
  callValuesListenersForChanges(1);
1570
1583
  }
1584
+ mutating = 0;
1571
1585
  if (doRollback?.(store)) {
1572
1586
  collForEach(changedCells, (table, tableId) =>
1573
1587
  collForEach(table, (row, rowId) =>
@@ -1934,6 +1948,7 @@ const createMergeableStore = (uniqueId, getNow) => {
1934
1948
  let listeningToRawStoreChanges = 1;
1935
1949
  let contentStampMap = newContentStampMap();
1936
1950
  let defaultingContent = 0;
1951
+ let mutated = 0;
1937
1952
  const touchedCells = mapNew();
1938
1953
  const touchedValues = setNew();
1939
1954
  const [getNextHlc, seenHlc] = getHlcFunctions(uniqueId, getNow);
@@ -2060,12 +2075,15 @@ const createMergeableStore = (uniqueId, getNow) => {
2060
2075
  collClear(touchedCells);
2061
2076
  collClear(touchedValues);
2062
2077
  };
2063
- const cellChanged = (tableId, rowId, cellId, newCell) => {
2078
+ const cellChanged = (tableId, rowId, cellId, newCell, mutating) => {
2064
2079
  setAdd(
2065
2080
  mapEnsure(mapEnsure(touchedCells, tableId, mapNew), rowId, setNew),
2066
2081
  cellId,
2067
2082
  );
2068
- if (listeningToRawStoreChanges) {
2083
+ if (listeningToRawStoreChanges || mutating) {
2084
+ if (mutating) {
2085
+ mutated = 1;
2086
+ }
2069
2087
  mergeContentOrChanges([
2070
2088
  [
2071
2089
  {
@@ -2088,9 +2106,12 @@ const createMergeableStore = (uniqueId, getNow) => {
2088
2106
  ]);
2089
2107
  }
2090
2108
  };
2091
- const valueChanged = (valueId, newValue) => {
2109
+ const valueChanged = (valueId, newValue, mutating) => {
2092
2110
  setAdd(touchedValues, valueId);
2093
- if (listeningToRawStoreChanges) {
2111
+ if (listeningToRawStoreChanges || mutating) {
2112
+ if (mutating) {
2113
+ mutated = 1;
2114
+ }
2094
2115
  mergeContentOrChanges([
2095
2116
  [{}],
2096
2117
  [
@@ -2308,6 +2329,11 @@ const createMergeableStore = (uniqueId, getNow) => {
2308
2329
  mergeableStore2.applyMergeableChanges(mergeableChanges);
2309
2330
  return applyMergeableChanges(mergeableChanges2);
2310
2331
  };
2332
+ const hadMutated = () => {
2333
+ const result = mutated;
2334
+ mutated = 0;
2335
+ return result;
2336
+ };
2311
2337
  const mergeableStore = {
2312
2338
  getMergeableContent,
2313
2339
  getMergeableContentHashes,
@@ -2324,6 +2350,8 @@ const createMergeableStore = (uniqueId, getNow) => {
2324
2350
  getTransactionMergeableChanges,
2325
2351
  applyMergeableChanges,
2326
2352
  merge,
2353
+ // only used internally by other modules
2354
+ hadMutated,
2327
2355
  };
2328
2356
  store.setInternalListeners(
2329
2357
  preStartTransaction,
@@ -184,31 +184,32 @@ const getValueInValuesHash = (valueId, valueHash) =>
184
184
  const getValueHash = (value, valueHlc) =>
185
185
  getHash(jsonStringWithMap(value ?? null) + ':' + valueHlc);
186
186
 
187
- const mapNew = (entries) => new Map(entries);
188
- const mapKeys = (map) => [...(map?.keys() ?? [])];
189
- const mapGet = (map, key) => map?.get(key);
190
- const mapForEach = (map, cb) =>
191
- collForEach(map, (value, key) => cb(key, value));
187
+ const map = Map;
188
+ const mapNew = (entries) => new map(entries);
189
+ const mapKeys = (map2) => [...(map2?.keys() ?? [])];
190
+ const mapGet = (map2, key) => map2?.get(key);
191
+ const mapForEach = (map2, cb) =>
192
+ collForEach(map2, (value, key) => cb(key, value));
192
193
  const mapMap = (coll, cb) =>
193
194
  arrayMap([...(coll?.entries() ?? [])], ([key, value]) => cb(value, key));
194
- const mapSet = (map, key, value) =>
195
- isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
196
- const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
197
- if (!collHas(map, key)) {
198
- mapSet(map, key, getDefaultValue());
195
+ const mapSet = (map2, key, value) =>
196
+ isUndefined(value) ? (collDel(map2, key), map2) : map2?.set(key, value);
197
+ const mapEnsure = (map2, key, getDefaultValue, hadExistingValue) => {
198
+ if (!collHas(map2, key)) {
199
+ mapSet(map2, key, getDefaultValue());
199
200
  } else {
200
- hadExistingValue?.(mapGet(map, key));
201
+ hadExistingValue?.(mapGet(map2, key));
201
202
  }
202
- return mapGet(map, key);
203
+ return mapGet(map2, key);
203
204
  };
204
- const mapMatch = (map, obj, set, del = mapSet) => {
205
- objMap(obj, (value, id) => set(map, id, value));
206
- mapForEach(map, (id) => (objHas(obj, id) ? 0 : del(map, id)));
207
- return map;
205
+ const mapMatch = (map2, obj, set, del = mapSet) => {
206
+ objMap(obj, (value, id) => set(map2, id, value));
207
+ mapForEach(map2, (id) => (objHas(obj, id) ? 0 : del(map2, id)));
208
+ return map2;
208
209
  };
209
- const mapToObj = (map, valueMapper, excludeMapValue, excludeObjValue) => {
210
+ const mapToObj = (map2, valueMapper, excludeMapValue, excludeObjValue) => {
210
211
  const obj = {};
211
- collForEach(map, (mapValue, id) => {
212
+ collForEach(map2, (mapValue, id) => {
212
213
  if (!excludeMapValue?.(mapValue, id)) {
213
214
  const objValue = valueMapper ? valueMapper(mapValue, id) : mapValue;
214
215
  if (!excludeObjValue?.(objValue)) {
@@ -218,27 +219,27 @@ const mapToObj = (map, valueMapper, excludeMapValue, excludeObjValue) => {
218
219
  });
219
220
  return obj;
220
221
  };
221
- const mapToObj2 = (map, valueMapper, excludeMapValue) =>
222
+ const mapToObj2 = (map2, valueMapper, excludeMapValue) =>
222
223
  mapToObj(
223
- map,
224
+ map2,
224
225
  (childMap) => mapToObj(childMap, valueMapper, excludeMapValue),
225
226
  collIsEmpty,
226
227
  objIsEmpty,
227
228
  );
228
- const mapToObj3 = (map, valueMapper, excludeMapValue) =>
229
+ const mapToObj3 = (map2, valueMapper, excludeMapValue) =>
229
230
  mapToObj(
230
- map,
231
+ map2,
231
232
  (childMap) => mapToObj2(childMap, valueMapper, excludeMapValue),
232
233
  collIsEmpty,
233
234
  objIsEmpty,
234
235
  );
235
- const mapClone = (map, mapValue) => {
236
- const map2 = mapNew();
237
- collForEach(map, (value, key) => map2.set(key, mapValue?.(value) ?? value));
238
- return map2;
236
+ const mapClone = (map2, mapValue) => {
237
+ const map22 = mapNew();
238
+ collForEach(map2, (value, key) => map22.set(key, mapValue?.(value) ?? value));
239
+ return map22;
239
240
  };
240
- const mapClone2 = (map) => mapClone(map, mapClone);
241
- const mapClone3 = (map) => mapClone(map, mapClone2);
241
+ const mapClone2 = (map2) => mapClone(map2, mapClone);
242
+ const mapClone3 = (map2) => mapClone(map2, mapClone2);
242
243
  const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
243
244
  ifNotUndefined(
244
245
  (ensureLeaf ? mapEnsure : mapGet)(
@@ -510,6 +511,7 @@ const createStore = () => {
510
511
  let hadValues = false;
511
512
  let transactions = 0;
512
513
  let internalListeners = [];
514
+ let mutating = 0;
513
515
  const changedTableIds = mapNew();
514
516
  const changedTableCellIds = mapNew();
515
517
  const changedRowCount = mapNew();
@@ -914,13 +916,13 @@ const createStore = () => {
914
916
  cellId,
915
917
  () => [oldCell, 0],
916
918
  )[1] = newCell;
917
- internalListeners[3]?.(tableId, rowId, cellId, newCell);
919
+ internalListeners[3]?.(tableId, rowId, cellId, newCell, mutating);
918
920
  };
919
921
  const valueIdsChanged = (valueId, addedOrRemoved) =>
920
922
  idsChanged(changedValueIds, valueId, addedOrRemoved);
921
923
  const valueChanged = (valueId, oldValue, newValue) => {
922
924
  mapEnsure(changedValues, valueId, () => [oldValue, 0])[1] = newValue;
923
- internalListeners[4]?.(valueId, newValue);
925
+ internalListeners[4]?.(valueId, newValue, mutating);
924
926
  };
925
927
  const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
926
928
  arrayPush(
@@ -995,14 +997,11 @@ const createStore = () => {
995
997
  }
996
998
  };
997
999
  const callTabularListenersForChanges = (mutator) => {
998
- const hasTablesNow = hasTables();
999
- if (hasTablesNow != hadTables) {
1000
- callListeners(hasTablesListeners[mutator], void 0, hasTablesNow);
1001
- }
1002
- const emptySortedRowIdListeners = collIsEmpty(
1000
+ const hasHasTablesListeners = !collIsEmpty(hasTablesListeners[mutator]);
1001
+ const hasSortedRowIdListeners = !collIsEmpty(
1003
1002
  sortedRowIdsListeners[mutator],
1004
1003
  );
1005
- const emptyIdAndHasListeners =
1004
+ const hasIdOrHasListeners = !(
1006
1005
  collIsEmpty(cellIdsListeners[mutator]) &&
1007
1006
  collIsEmpty(hasCellListeners[mutator]) &&
1008
1007
  collIsEmpty(rowIdsListeners[mutator]) &&
@@ -1010,15 +1009,17 @@ const createStore = () => {
1010
1009
  collIsEmpty(tableCellIdsListeners[mutator]) &&
1011
1010
  collIsEmpty(hasTableCellListeners[mutator]) &&
1012
1011
  collIsEmpty(rowCountListeners[mutator]) &&
1013
- emptySortedRowIdListeners &&
1012
+ !hasSortedRowIdListeners &&
1014
1013
  collIsEmpty(tableIdsListeners[mutator]) &&
1015
- collIsEmpty(hasTableListeners[mutator]);
1016
- const emptyOtherListeners =
1014
+ collIsEmpty(hasTableListeners[mutator])
1015
+ );
1016
+ const hasOtherListeners = !(
1017
1017
  collIsEmpty(cellListeners[mutator]) &&
1018
1018
  collIsEmpty(rowListeners[mutator]) &&
1019
1019
  collIsEmpty(tableListeners[mutator]) &&
1020
- collIsEmpty(tablesListeners[mutator]);
1021
- if (!emptyIdAndHasListeners || !emptyOtherListeners) {
1020
+ collIsEmpty(tablesListeners[mutator])
1021
+ );
1022
+ if (hasHasTablesListeners || hasIdOrHasListeners || hasOtherListeners) {
1022
1023
  const changes = mutator
1023
1024
  ? [
1024
1025
  mapClone(changedTableIds),
@@ -1026,7 +1027,9 @@ const createStore = () => {
1026
1027
  mapClone(changedRowCount),
1027
1028
  mapClone2(changedRowIds),
1028
1029
  mapClone3(changedCellIds),
1029
- mapClone3(changedCells),
1030
+ mapClone(changedCells, (map) =>
1031
+ mapClone(map, (map2) => mapClone(map2, pairClone)),
1032
+ ),
1030
1033
  ]
1031
1034
  : [
1032
1035
  changedTableIds,
@@ -1036,7 +1039,13 @@ const createStore = () => {
1036
1039
  changedCellIds,
1037
1040
  changedCells,
1038
1041
  ];
1039
- if (!emptyIdAndHasListeners) {
1042
+ if (hasHasTablesListeners) {
1043
+ const hasTablesNow = hasTables();
1044
+ if (hasTablesNow != hadTables) {
1045
+ callListeners(hasTablesListeners[mutator], void 0, hasTablesNow);
1046
+ }
1047
+ }
1048
+ if (hasIdOrHasListeners) {
1040
1049
  callIdsAndHasListenersIfChanged(
1041
1050
  changes[0],
1042
1051
  tableIdsListeners[mutator],
@@ -1068,13 +1077,13 @@ const createStore = () => {
1068
1077
  hasRowListeners[mutator],
1069
1078
  [tableId],
1070
1079
  ) &&
1071
- !emptySortedRowIdListeners
1080
+ hasSortedRowIdListeners
1072
1081
  ) {
1073
1082
  callListeners(sortedRowIdsListeners[mutator], [tableId, null]);
1074
1083
  setAdd(calledSortableTableIds, tableId);
1075
1084
  }
1076
1085
  });
1077
- if (!emptySortedRowIdListeners) {
1086
+ if (hasSortedRowIdListeners) {
1078
1087
  collForEach(changes[5], (rows, tableId) => {
1079
1088
  if (!collHas(calledSortableTableIds, tableId)) {
1080
1089
  const sortableCellIds = setNew();
@@ -1105,7 +1114,7 @@ const createStore = () => {
1105
1114
  ),
1106
1115
  );
1107
1116
  }
1108
- if (!emptyOtherListeners) {
1117
+ if (hasOtherListeners) {
1109
1118
  let tablesChanged;
1110
1119
  collForEach(changes[5], (rows, tableId) => {
1111
1120
  let tableChanged;
@@ -1142,28 +1151,31 @@ const createStore = () => {
1142
1151
  }
1143
1152
  };
1144
1153
  const callValuesListenersForChanges = (mutator) => {
1145
- const hasValuesNow = hasValues();
1146
- if (hasValuesNow != hadValues) {
1147
- callListeners(hasValuesListeners[mutator], void 0, hasValuesNow);
1148
- }
1149
- const emptyIdAndHasListeners =
1150
- collIsEmpty(valueIdsListeners[mutator]) &&
1151
- collIsEmpty(hasValueListeners[mutator]);
1152
- const emptyOtherListeners =
1153
- collIsEmpty(valueListeners[mutator]) &&
1154
- collIsEmpty(valuesListeners[mutator]);
1155
- if (!emptyIdAndHasListeners || !emptyOtherListeners) {
1154
+ const hasHasValuesListeners = !collIsEmpty(hasValuesListeners[mutator]);
1155
+ const hasIdOrHasListeners =
1156
+ !collIsEmpty(valueIdsListeners[mutator]) ||
1157
+ !collIsEmpty(hasValueListeners[mutator]);
1158
+ const hasOtherListeners =
1159
+ !collIsEmpty(valueListeners[mutator]) ||
1160
+ !collIsEmpty(valuesListeners[mutator]);
1161
+ if (hasHasValuesListeners || hasIdOrHasListeners || hasOtherListeners) {
1156
1162
  const changes = mutator
1157
- ? [mapClone(changedValueIds), mapClone(changedValues)]
1163
+ ? [mapClone(changedValueIds), mapClone(changedValues, pairClone)]
1158
1164
  : [changedValueIds, changedValues];
1159
- if (!emptyIdAndHasListeners) {
1165
+ if (hasHasValuesListeners) {
1166
+ const hasValuesNow = hasValues();
1167
+ if (hasValuesNow != hadValues) {
1168
+ callListeners(hasValuesListeners[mutator], void 0, hasValuesNow);
1169
+ }
1170
+ }
1171
+ if (hasIdOrHasListeners) {
1160
1172
  callIdsAndHasListenersIfChanged(
1161
1173
  changes[0],
1162
1174
  valueIdsListeners[mutator],
1163
1175
  hasValueListeners[mutator],
1164
1176
  );
1165
1177
  }
1166
- if (!emptyOtherListeners) {
1178
+ if (hasOtherListeners) {
1167
1179
  let valuesChanged;
1168
1180
  collForEach(changes[1], ([oldValue, newValue], valueId) => {
1169
1181
  if (newValue !== oldValue) {
@@ -1560,6 +1572,7 @@ const createStore = () => {
1560
1572
  transactions--;
1561
1573
  if (transactions == 0) {
1562
1574
  transactions = 1;
1575
+ mutating = 1;
1563
1576
  callInvalidCellListeners(1);
1564
1577
  if (!collIsEmpty(changedCells)) {
1565
1578
  callTabularListenersForChanges(1);
@@ -1568,6 +1581,7 @@ const createStore = () => {
1568
1581
  if (!collIsEmpty(changedValues)) {
1569
1582
  callValuesListenersForChanges(1);
1570
1583
  }
1584
+ mutating = 0;
1571
1585
  if (doRollback?.(store)) {
1572
1586
  collForEach(changedCells, (table, tableId) =>
1573
1587
  collForEach(table, (row, rowId) =>
@@ -1934,6 +1948,7 @@ const createMergeableStore = (uniqueId, getNow) => {
1934
1948
  let listeningToRawStoreChanges = 1;
1935
1949
  let contentStampMap = newContentStampMap();
1936
1950
  let defaultingContent = 0;
1951
+ let mutated = 0;
1937
1952
  const touchedCells = mapNew();
1938
1953
  const touchedValues = setNew();
1939
1954
  const [getNextHlc, seenHlc] = getHlcFunctions(uniqueId, getNow);
@@ -2060,12 +2075,15 @@ const createMergeableStore = (uniqueId, getNow) => {
2060
2075
  collClear(touchedCells);
2061
2076
  collClear(touchedValues);
2062
2077
  };
2063
- const cellChanged = (tableId, rowId, cellId, newCell) => {
2078
+ const cellChanged = (tableId, rowId, cellId, newCell, mutating) => {
2064
2079
  setAdd(
2065
2080
  mapEnsure(mapEnsure(touchedCells, tableId, mapNew), rowId, setNew),
2066
2081
  cellId,
2067
2082
  );
2068
- if (listeningToRawStoreChanges) {
2083
+ if (listeningToRawStoreChanges || mutating) {
2084
+ if (mutating) {
2085
+ mutated = 1;
2086
+ }
2069
2087
  mergeContentOrChanges([
2070
2088
  [
2071
2089
  {
@@ -2088,9 +2106,12 @@ const createMergeableStore = (uniqueId, getNow) => {
2088
2106
  ]);
2089
2107
  }
2090
2108
  };
2091
- const valueChanged = (valueId, newValue) => {
2109
+ const valueChanged = (valueId, newValue, mutating) => {
2092
2110
  setAdd(touchedValues, valueId);
2093
- if (listeningToRawStoreChanges) {
2111
+ if (listeningToRawStoreChanges || mutating) {
2112
+ if (mutating) {
2113
+ mutated = 1;
2114
+ }
2094
2115
  mergeContentOrChanges([
2095
2116
  [{}],
2096
2117
  [
@@ -2308,6 +2329,11 @@ const createMergeableStore = (uniqueId, getNow) => {
2308
2329
  mergeableStore2.applyMergeableChanges(mergeableChanges);
2309
2330
  return applyMergeableChanges(mergeableChanges2);
2310
2331
  };
2332
+ const hadMutated = () => {
2333
+ const result = mutated;
2334
+ mutated = 0;
2335
+ return result;
2336
+ };
2311
2337
  const mergeableStore = {
2312
2338
  getMergeableContent,
2313
2339
  getMergeableContentHashes,
@@ -2324,6 +2350,8 @@ const createMergeableStore = (uniqueId, getNow) => {
2324
2350
  getTransactionMergeableChanges,
2325
2351
  applyMergeableChanges,
2326
2352
  merge,
2353
+ // only used internally by other modules
2354
+ hadMutated,
2327
2355
  };
2328
2356
  store.setInternalListeners(
2329
2357
  preStartTransaction,