tinybase 7.3.2 → 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 (249) 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-partykit-server/index.js +1 -1
  85. package/min/persisters/persister-partykit-server/index.js.gz +0 -0
  86. package/min/persisters/persister-partykit-server/with-schemas/index.js +1 -1
  87. package/min/persisters/persister-partykit-server/with-schemas/index.js.gz +0 -0
  88. package/min/persisters/persister-pglite/index.js +1 -1
  89. package/min/persisters/persister-pglite/index.js.gz +0 -0
  90. package/min/persisters/persister-pglite/with-schemas/index.js +1 -1
  91. package/min/persisters/persister-pglite/with-schemas/index.js.gz +0 -0
  92. package/min/persisters/persister-postgres/index.js +1 -1
  93. package/min/persisters/persister-postgres/index.js.gz +0 -0
  94. package/min/persisters/persister-postgres/with-schemas/index.js +1 -1
  95. package/min/persisters/persister-postgres/with-schemas/index.js.gz +0 -0
  96. package/min/persisters/persister-powersync/index.js +1 -1
  97. package/min/persisters/persister-powersync/index.js.gz +0 -0
  98. package/min/persisters/persister-powersync/with-schemas/index.js +1 -1
  99. package/min/persisters/persister-powersync/with-schemas/index.js.gz +0 -0
  100. package/min/persisters/persister-react-native-mmkv/index.js +1 -1
  101. package/min/persisters/persister-react-native-mmkv/index.js.gz +0 -0
  102. package/min/persisters/persister-react-native-mmkv/with-schemas/index.js +1 -1
  103. package/min/persisters/persister-react-native-mmkv/with-schemas/index.js.gz +0 -0
  104. package/min/persisters/persister-react-native-sqlite/index.js +1 -1
  105. package/min/persisters/persister-react-native-sqlite/index.js.gz +0 -0
  106. package/min/persisters/persister-react-native-sqlite/with-schemas/index.js +1 -1
  107. package/min/persisters/persister-react-native-sqlite/with-schemas/index.js.gz +0 -0
  108. package/min/persisters/persister-remote/index.js +1 -1
  109. package/min/persisters/persister-remote/index.js.gz +0 -0
  110. package/min/persisters/persister-remote/with-schemas/index.js +1 -1
  111. package/min/persisters/persister-remote/with-schemas/index.js.gz +0 -0
  112. package/min/persisters/persister-sqlite-bun/index.js +1 -1
  113. package/min/persisters/persister-sqlite-bun/index.js.gz +0 -0
  114. package/min/persisters/persister-sqlite-bun/with-schemas/index.js +1 -1
  115. package/min/persisters/persister-sqlite-bun/with-schemas/index.js.gz +0 -0
  116. package/min/persisters/persister-sqlite-wasm/index.js +1 -1
  117. package/min/persisters/persister-sqlite-wasm/index.js.gz +0 -0
  118. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js +1 -1
  119. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js.gz +0 -0
  120. package/min/persisters/persister-sqlite3/index.js +1 -1
  121. package/min/persisters/persister-sqlite3/index.js.gz +0 -0
  122. package/min/persisters/persister-sqlite3/with-schemas/index.js +1 -1
  123. package/min/persisters/persister-sqlite3/with-schemas/index.js.gz +0 -0
  124. package/min/persisters/persister-yjs/index.js +1 -1
  125. package/min/persisters/persister-yjs/index.js.gz +0 -0
  126. package/min/persisters/persister-yjs/with-schemas/index.js +1 -1
  127. package/min/persisters/persister-yjs/with-schemas/index.js.gz +0 -0
  128. package/min/persisters/with-schemas/index.js +1 -1
  129. package/min/persisters/with-schemas/index.js.gz +0 -0
  130. package/min/queries/index.js +1 -1
  131. package/min/queries/index.js.gz +0 -0
  132. package/min/queries/with-schemas/index.js +1 -1
  133. package/min/queries/with-schemas/index.js.gz +0 -0
  134. package/min/relationships/index.js +1 -1
  135. package/min/relationships/index.js.gz +0 -0
  136. package/min/relationships/with-schemas/index.js +1 -1
  137. package/min/relationships/with-schemas/index.js.gz +0 -0
  138. package/min/store/index.js +1 -1
  139. package/min/store/index.js.gz +0 -0
  140. package/min/store/with-schemas/index.js +1 -1
  141. package/min/store/with-schemas/index.js.gz +0 -0
  142. package/min/synchronizers/index.js +1 -1
  143. package/min/synchronizers/index.js.gz +0 -0
  144. package/min/synchronizers/synchronizer-broadcast-channel/index.js +1 -1
  145. package/min/synchronizers/synchronizer-broadcast-channel/index.js.gz +0 -0
  146. package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +1 -1
  147. package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js.gz +0 -0
  148. package/min/synchronizers/synchronizer-local/index.js +1 -1
  149. package/min/synchronizers/synchronizer-local/index.js.gz +0 -0
  150. package/min/synchronizers/synchronizer-local/with-schemas/index.js +1 -1
  151. package/min/synchronizers/synchronizer-local/with-schemas/index.js.gz +0 -0
  152. package/min/synchronizers/synchronizer-ws-client/index.js +1 -1
  153. package/min/synchronizers/synchronizer-ws-client/index.js.gz +0 -0
  154. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js +1 -1
  155. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js.gz +0 -0
  156. package/min/synchronizers/synchronizer-ws-server/index.js +1 -1
  157. package/min/synchronizers/synchronizer-ws-server/index.js.gz +0 -0
  158. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js +1 -1
  159. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js.gz +0 -0
  160. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js +1 -1
  161. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js.gz +0 -0
  162. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +1 -1
  163. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js.gz +0 -0
  164. package/min/synchronizers/synchronizer-ws-server-simple/index.js +1 -1
  165. package/min/synchronizers/synchronizer-ws-server-simple/index.js.gz +0 -0
  166. package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +1 -1
  167. package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js.gz +0 -0
  168. package/min/synchronizers/with-schemas/index.js +1 -1
  169. package/min/synchronizers/with-schemas/index.js.gz +0 -0
  170. package/min/ui-react-inspector/index.js +1 -1
  171. package/min/ui-react-inspector/index.js.gz +0 -0
  172. package/min/ui-react-inspector/with-schemas/index.js +1 -1
  173. package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
  174. package/min/with-schemas/index.js +1 -1
  175. package/min/with-schemas/index.js.gz +0 -0
  176. package/omni/index.js +115 -67
  177. package/omni/with-schemas/index.js +115 -67
  178. package/package.json +13 -13
  179. package/persisters/index.js +29 -12
  180. package/persisters/persister-automerge/index.js +17 -9
  181. package/persisters/persister-automerge/with-schemas/index.js +17 -9
  182. package/persisters/persister-browser/index.js +34 -10
  183. package/persisters/persister-browser/with-schemas/index.js +34 -10
  184. package/persisters/persister-cr-sqlite-wasm/index.js +29 -12
  185. package/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +29 -12
  186. package/persisters/persister-durable-object-sql-storage/index.js +29 -12
  187. package/persisters/persister-durable-object-sql-storage/with-schemas/index.js +29 -12
  188. package/persisters/persister-durable-object-storage/index.js +19 -11
  189. package/persisters/persister-durable-object-storage/with-schemas/index.js +19 -11
  190. package/persisters/persister-electric-sql/index.js +29 -12
  191. package/persisters/persister-electric-sql/with-schemas/index.js +29 -12
  192. package/persisters/persister-expo-sqlite/index.js +29 -12
  193. package/persisters/persister-expo-sqlite/with-schemas/index.js +29 -12
  194. package/persisters/persister-file/index.js +34 -10
  195. package/persisters/persister-file/with-schemas/index.js +34 -10
  196. package/persisters/persister-indexed-db/index.js +17 -9
  197. package/persisters/persister-indexed-db/with-schemas/index.js +17 -9
  198. package/persisters/persister-libsql/index.js +29 -12
  199. package/persisters/persister-libsql/with-schemas/index.js +29 -12
  200. package/persisters/persister-partykit-client/index.js +44 -11
  201. package/persisters/persister-partykit-client/with-schemas/index.js +44 -11
  202. package/persisters/persister-partykit-server/index.js +39 -4
  203. package/persisters/persister-partykit-server/with-schemas/index.js +39 -4
  204. package/persisters/persister-pglite/index.js +29 -12
  205. package/persisters/persister-pglite/with-schemas/index.js +29 -12
  206. package/persisters/persister-postgres/index.js +29 -12
  207. package/persisters/persister-postgres/with-schemas/index.js +29 -12
  208. package/persisters/persister-powersync/index.js +29 -12
  209. package/persisters/persister-powersync/with-schemas/index.js +29 -12
  210. package/persisters/persister-react-native-mmkv/index.js +17 -9
  211. package/persisters/persister-react-native-mmkv/with-schemas/index.js +17 -9
  212. package/persisters/persister-react-native-sqlite/index.js +29 -12
  213. package/persisters/persister-react-native-sqlite/with-schemas/index.js +29 -12
  214. package/persisters/persister-remote/index.js +17 -9
  215. package/persisters/persister-remote/with-schemas/index.js +17 -9
  216. package/persisters/persister-sqlite-bun/index.js +29 -12
  217. package/persisters/persister-sqlite-bun/with-schemas/index.js +29 -12
  218. package/persisters/persister-sqlite-wasm/index.js +29 -12
  219. package/persisters/persister-sqlite-wasm/with-schemas/index.js +29 -12
  220. package/persisters/persister-sqlite3/index.js +29 -12
  221. package/persisters/persister-sqlite3/with-schemas/index.js +29 -12
  222. package/persisters/persister-yjs/index.js +19 -11
  223. package/persisters/persister-yjs/with-schemas/index.js +19 -11
  224. package/persisters/with-schemas/index.js +29 -12
  225. package/queries/index.js +15 -14
  226. package/queries/with-schemas/index.js +15 -14
  227. package/readme.md +10 -2
  228. package/relationships/index.js +13 -12
  229. package/relationships/with-schemas/index.js +13 -12
  230. package/releases.md +1 -1
  231. package/store/index.js +74 -60
  232. package/store/with-schemas/index.js +74 -60
  233. package/synchronizers/index.js +17 -9
  234. package/synchronizers/synchronizer-broadcast-channel/index.js +17 -9
  235. package/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +17 -9
  236. package/synchronizers/synchronizer-local/index.js +19 -11
  237. package/synchronizers/synchronizer-local/with-schemas/index.js +19 -11
  238. package/synchronizers/synchronizer-ws-client/index.js +31 -10
  239. package/synchronizers/synchronizer-ws-client/with-schemas/index.js +31 -10
  240. package/synchronizers/synchronizer-ws-server/index.js +34 -13
  241. package/synchronizers/synchronizer-ws-server/with-schemas/index.js +34 -13
  242. package/synchronizers/synchronizer-ws-server-durable-object/index.js +31 -10
  243. package/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +31 -10
  244. package/synchronizers/synchronizer-ws-server-simple/index.js +11 -10
  245. package/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +11 -10
  246. package/synchronizers/with-schemas/index.js +17 -9
  247. package/ui-react-inspector/index.js +91 -61
  248. package/ui-react-inspector/with-schemas/index.js +91 -61
  249. package/with-schemas/index.js +92 -64
@@ -276,31 +276,32 @@ const objValidate = (obj, validateChild, onInvalidObj, emptyIsValid = 0) => {
276
276
  return emptyIsValid ? true : !objIsEmpty(obj);
277
277
  };
278
278
 
279
- const mapNew = (entries) => new Map(entries);
280
- const mapKeys = (map) => [...(map?.keys() ?? [])];
281
- const mapGet = (map, key) => map?.get(key);
282
- const mapForEach = (map, cb) =>
283
- collForEach(map, (value, key) => cb(key, value));
279
+ const map = Map;
280
+ const mapNew = (entries) => new map(entries);
281
+ const mapKeys = (map2) => [...(map2?.keys() ?? [])];
282
+ const mapGet = (map2, key) => map2?.get(key);
283
+ const mapForEach = (map2, cb) =>
284
+ collForEach(map2, (value, key) => cb(key, value));
284
285
  const mapMap = (coll, cb) =>
285
286
  arrayMap([...(coll?.entries() ?? [])], ([key, value]) => cb(value, key));
286
- const mapSet = (map, key, value) =>
287
- isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
288
- const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
289
- if (!collHas(map, key)) {
290
- mapSet(map, key, getDefaultValue());
287
+ const mapSet = (map2, key, value) =>
288
+ isUndefined(value) ? (collDel(map2, key), map2) : map2?.set(key, value);
289
+ const mapEnsure = (map2, key, getDefaultValue, hadExistingValue) => {
290
+ if (!collHas(map2, key)) {
291
+ mapSet(map2, key, getDefaultValue());
291
292
  } else {
292
- hadExistingValue?.(mapGet(map, key));
293
+ hadExistingValue?.(mapGet(map2, key));
293
294
  }
294
- return mapGet(map, key);
295
+ return mapGet(map2, key);
295
296
  };
296
- const mapMatch = (map, obj, set, del = mapSet) => {
297
- objMap(obj, (value, id) => set(map, id, value));
298
- mapForEach(map, (id) => (objHas(obj, id) ? 0 : del(map, id)));
299
- return map;
297
+ const mapMatch = (map2, obj, set, del = mapSet) => {
298
+ objMap(obj, (value, id) => set(map2, id, value));
299
+ mapForEach(map2, (id) => (objHas(obj, id) ? 0 : del(map2, id)));
300
+ return map2;
300
301
  };
301
- const mapToObj = (map, valueMapper, excludeMapValue, excludeObjValue) => {
302
+ const mapToObj = (map2, valueMapper, excludeMapValue, excludeObjValue) => {
302
303
  const obj = {};
303
- collForEach(map, (mapValue, id) => {
304
+ collForEach(map2, (mapValue, id) => {
304
305
  if (!excludeMapValue?.(mapValue, id)) {
305
306
  const objValue = valueMapper ? valueMapper(mapValue, id) : mapValue;
306
307
  if (!excludeObjValue?.(objValue)) {
@@ -310,27 +311,27 @@ const mapToObj = (map, valueMapper, excludeMapValue, excludeObjValue) => {
310
311
  });
311
312
  return obj;
312
313
  };
313
- const mapToObj2 = (map, valueMapper, excludeMapValue) =>
314
+ const mapToObj2 = (map2, valueMapper, excludeMapValue) =>
314
315
  mapToObj(
315
- map,
316
+ map2,
316
317
  (childMap) => mapToObj(childMap, valueMapper, excludeMapValue),
317
318
  collIsEmpty,
318
319
  objIsEmpty,
319
320
  );
320
- const mapToObj3 = (map, valueMapper, excludeMapValue) =>
321
+ const mapToObj3 = (map2, valueMapper, excludeMapValue) =>
321
322
  mapToObj(
322
- map,
323
+ map2,
323
324
  (childMap) => mapToObj2(childMap, valueMapper, excludeMapValue),
324
325
  collIsEmpty,
325
326
  objIsEmpty,
326
327
  );
327
- const mapClone = (map, mapValue) => {
328
- const map2 = mapNew();
329
- collForEach(map, (value, key) => map2.set(key, mapValue?.(value) ?? value));
330
- return map2;
328
+ const mapClone = (map2, mapValue) => {
329
+ const map22 = mapNew();
330
+ collForEach(map2, (value, key) => map22.set(key, mapValue?.(value) ?? value));
331
+ return map22;
331
332
  };
332
- const mapClone2 = (map) => mapClone(map, mapClone);
333
- const mapClone3 = (map) => mapClone(map, mapClone2);
333
+ const mapClone2 = (map2) => mapClone(map2, mapClone);
334
+ const mapClone3 = (map2) => mapClone(map2, mapClone2);
334
335
  const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
335
336
  ifNotUndefined(
336
337
  (ensureLeaf ? mapEnsure : mapGet)(
@@ -899,7 +900,16 @@ const jsonStringWithMap = (obj) =>
899
900
  const jsonStringWithUndefined = (obj) =>
900
901
  jsonString(obj, (_key, value) => (isUndefined(value) ? UNDEFINED : value));
901
902
  const jsonParseWithUndefined = (str) =>
902
- jsonParse(str, (_key, value) => (value === UNDEFINED ? void 0 : value));
903
+ // JSON.parse reviver removes properties with undefined values
904
+ replaceUndefinedString(jsonParse(str));
905
+ const replaceUndefinedString = (obj) =>
906
+ obj === UNDEFINED
907
+ ? void 0
908
+ : isArray(obj)
909
+ ? arrayMap(obj, replaceUndefinedString)
910
+ : isObject(obj)
911
+ ? objMap(obj, replaceUndefinedString)
912
+ : obj;
903
913
 
904
914
  const textEncoder = /* @__PURE__ */ new GLOBAL.TextEncoder();
905
915
  const getHash = (string) => {
@@ -1290,6 +1300,7 @@ const createStore = () => {
1290
1300
  let hadValues = false;
1291
1301
  let transactions = 0;
1292
1302
  let internalListeners = [];
1303
+ let mutating = 0;
1293
1304
  const changedTableIds = mapNew();
1294
1305
  const changedTableCellIds = mapNew();
1295
1306
  const changedRowCount = mapNew();
@@ -1694,13 +1705,13 @@ const createStore = () => {
1694
1705
  cellId,
1695
1706
  () => [oldCell, 0],
1696
1707
  )[1] = newCell;
1697
- internalListeners[3]?.(tableId, rowId, cellId, newCell);
1708
+ internalListeners[3]?.(tableId, rowId, cellId, newCell, mutating);
1698
1709
  };
1699
1710
  const valueIdsChanged = (valueId, addedOrRemoved) =>
1700
1711
  idsChanged(changedValueIds, valueId, addedOrRemoved);
1701
1712
  const valueChanged = (valueId, oldValue, newValue) => {
1702
1713
  mapEnsure(changedValues, valueId, () => [oldValue, 0])[1] = newValue;
1703
- internalListeners[4]?.(valueId, newValue);
1714
+ internalListeners[4]?.(valueId, newValue, mutating);
1704
1715
  };
1705
1716
  const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
1706
1717
  arrayPush(
@@ -1775,14 +1786,11 @@ const createStore = () => {
1775
1786
  }
1776
1787
  };
1777
1788
  const callTabularListenersForChanges = (mutator) => {
1778
- const hasTablesNow = hasTables();
1779
- if (hasTablesNow != hadTables) {
1780
- callListeners(hasTablesListeners[mutator], void 0, hasTablesNow);
1781
- }
1782
- const emptySortedRowIdListeners = collIsEmpty(
1789
+ const hasHasTablesListeners = !collIsEmpty(hasTablesListeners[mutator]);
1790
+ const hasSortedRowIdListeners = !collIsEmpty(
1783
1791
  sortedRowIdsListeners[mutator],
1784
1792
  );
1785
- const emptyIdAndHasListeners =
1793
+ const hasIdOrHasListeners = !(
1786
1794
  collIsEmpty(cellIdsListeners[mutator]) &&
1787
1795
  collIsEmpty(hasCellListeners[mutator]) &&
1788
1796
  collIsEmpty(rowIdsListeners[mutator]) &&
@@ -1790,15 +1798,17 @@ const createStore = () => {
1790
1798
  collIsEmpty(tableCellIdsListeners[mutator]) &&
1791
1799
  collIsEmpty(hasTableCellListeners[mutator]) &&
1792
1800
  collIsEmpty(rowCountListeners[mutator]) &&
1793
- emptySortedRowIdListeners &&
1801
+ !hasSortedRowIdListeners &&
1794
1802
  collIsEmpty(tableIdsListeners[mutator]) &&
1795
- collIsEmpty(hasTableListeners[mutator]);
1796
- const emptyOtherListeners =
1803
+ collIsEmpty(hasTableListeners[mutator])
1804
+ );
1805
+ const hasOtherListeners = !(
1797
1806
  collIsEmpty(cellListeners[mutator]) &&
1798
1807
  collIsEmpty(rowListeners[mutator]) &&
1799
1808
  collIsEmpty(tableListeners[mutator]) &&
1800
- collIsEmpty(tablesListeners[mutator]);
1801
- if (!emptyIdAndHasListeners || !emptyOtherListeners) {
1809
+ collIsEmpty(tablesListeners[mutator])
1810
+ );
1811
+ if (hasHasTablesListeners || hasIdOrHasListeners || hasOtherListeners) {
1802
1812
  const changes = mutator
1803
1813
  ? [
1804
1814
  mapClone(changedTableIds),
@@ -1806,7 +1816,9 @@ const createStore = () => {
1806
1816
  mapClone(changedRowCount),
1807
1817
  mapClone2(changedRowIds),
1808
1818
  mapClone3(changedCellIds),
1809
- mapClone3(changedCells),
1819
+ mapClone(changedCells, (map) =>
1820
+ mapClone(map, (map2) => mapClone(map2, pairClone)),
1821
+ ),
1810
1822
  ]
1811
1823
  : [
1812
1824
  changedTableIds,
@@ -1816,7 +1828,13 @@ const createStore = () => {
1816
1828
  changedCellIds,
1817
1829
  changedCells,
1818
1830
  ];
1819
- if (!emptyIdAndHasListeners) {
1831
+ if (hasHasTablesListeners) {
1832
+ const hasTablesNow = hasTables();
1833
+ if (hasTablesNow != hadTables) {
1834
+ callListeners(hasTablesListeners[mutator], void 0, hasTablesNow);
1835
+ }
1836
+ }
1837
+ if (hasIdOrHasListeners) {
1820
1838
  callIdsAndHasListenersIfChanged(
1821
1839
  changes[0],
1822
1840
  tableIdsListeners[mutator],
@@ -1848,13 +1866,13 @@ const createStore = () => {
1848
1866
  hasRowListeners[mutator],
1849
1867
  [tableId],
1850
1868
  ) &&
1851
- !emptySortedRowIdListeners
1869
+ hasSortedRowIdListeners
1852
1870
  ) {
1853
1871
  callListeners(sortedRowIdsListeners[mutator], [tableId, null]);
1854
1872
  setAdd(calledSortableTableIds, tableId);
1855
1873
  }
1856
1874
  });
1857
- if (!emptySortedRowIdListeners) {
1875
+ if (hasSortedRowIdListeners) {
1858
1876
  collForEach(changes[5], (rows, tableId) => {
1859
1877
  if (!collHas(calledSortableTableIds, tableId)) {
1860
1878
  const sortableCellIds = setNew();
@@ -1885,7 +1903,7 @@ const createStore = () => {
1885
1903
  ),
1886
1904
  );
1887
1905
  }
1888
- if (!emptyOtherListeners) {
1906
+ if (hasOtherListeners) {
1889
1907
  let tablesChanged;
1890
1908
  collForEach(changes[5], (rows, tableId) => {
1891
1909
  let tableChanged;
@@ -1922,28 +1940,31 @@ const createStore = () => {
1922
1940
  }
1923
1941
  };
1924
1942
  const callValuesListenersForChanges = (mutator) => {
1925
- const hasValuesNow = hasValues();
1926
- if (hasValuesNow != hadValues) {
1927
- callListeners(hasValuesListeners[mutator], void 0, hasValuesNow);
1928
- }
1929
- const emptyIdAndHasListeners =
1930
- collIsEmpty(valueIdsListeners[mutator]) &&
1931
- collIsEmpty(hasValueListeners[mutator]);
1932
- const emptyOtherListeners =
1933
- collIsEmpty(valueListeners[mutator]) &&
1934
- collIsEmpty(valuesListeners[mutator]);
1935
- if (!emptyIdAndHasListeners || !emptyOtherListeners) {
1943
+ const hasHasValuesListeners = !collIsEmpty(hasValuesListeners[mutator]);
1944
+ const hasIdOrHasListeners =
1945
+ !collIsEmpty(valueIdsListeners[mutator]) ||
1946
+ !collIsEmpty(hasValueListeners[mutator]);
1947
+ const hasOtherListeners =
1948
+ !collIsEmpty(valueListeners[mutator]) ||
1949
+ !collIsEmpty(valuesListeners[mutator]);
1950
+ if (hasHasValuesListeners || hasIdOrHasListeners || hasOtherListeners) {
1936
1951
  const changes = mutator
1937
- ? [mapClone(changedValueIds), mapClone(changedValues)]
1952
+ ? [mapClone(changedValueIds), mapClone(changedValues, pairClone)]
1938
1953
  : [changedValueIds, changedValues];
1939
- if (!emptyIdAndHasListeners) {
1954
+ if (hasHasValuesListeners) {
1955
+ const hasValuesNow = hasValues();
1956
+ if (hasValuesNow != hadValues) {
1957
+ callListeners(hasValuesListeners[mutator], void 0, hasValuesNow);
1958
+ }
1959
+ }
1960
+ if (hasIdOrHasListeners) {
1940
1961
  callIdsAndHasListenersIfChanged(
1941
1962
  changes[0],
1942
1963
  valueIdsListeners[mutator],
1943
1964
  hasValueListeners[mutator],
1944
1965
  );
1945
1966
  }
1946
- if (!emptyOtherListeners) {
1967
+ if (hasOtherListeners) {
1947
1968
  let valuesChanged;
1948
1969
  collForEach(changes[1], ([oldValue, newValue], valueId) => {
1949
1970
  if (newValue !== oldValue) {
@@ -2340,6 +2361,7 @@ const createStore = () => {
2340
2361
  transactions--;
2341
2362
  if (transactions == 0) {
2342
2363
  transactions = 1;
2364
+ mutating = 1;
2343
2365
  callInvalidCellListeners(1);
2344
2366
  if (!collIsEmpty(changedCells)) {
2345
2367
  callTabularListenersForChanges(1);
@@ -2348,6 +2370,7 @@ const createStore = () => {
2348
2370
  if (!collIsEmpty(changedValues)) {
2349
2371
  callValuesListenersForChanges(1);
2350
2372
  }
2373
+ mutating = 0;
2351
2374
  if (doRollback?.(store)) {
2352
2375
  collForEach(changedCells, (table, tableId) =>
2353
2376
  collForEach(table, (row, rowId) =>
@@ -2714,6 +2737,7 @@ const createMergeableStore = (uniqueId, getNow) => {
2714
2737
  let listeningToRawStoreChanges = 1;
2715
2738
  let contentStampMap = newContentStampMap();
2716
2739
  let defaultingContent = 0;
2740
+ let mutated = 0;
2717
2741
  const touchedCells = mapNew();
2718
2742
  const touchedValues = setNew();
2719
2743
  const [getNextHlc, seenHlc] = getHlcFunctions(uniqueId, getNow);
@@ -2840,12 +2864,15 @@ const createMergeableStore = (uniqueId, getNow) => {
2840
2864
  collClear(touchedCells);
2841
2865
  collClear(touchedValues);
2842
2866
  };
2843
- const cellChanged = (tableId, rowId, cellId, newCell) => {
2867
+ const cellChanged = (tableId, rowId, cellId, newCell, mutating) => {
2844
2868
  setAdd(
2845
2869
  mapEnsure(mapEnsure(touchedCells, tableId, mapNew), rowId, setNew),
2846
2870
  cellId,
2847
2871
  );
2848
- if (listeningToRawStoreChanges) {
2872
+ if (listeningToRawStoreChanges || mutating) {
2873
+ if (mutating) {
2874
+ mutated = 1;
2875
+ }
2849
2876
  mergeContentOrChanges([
2850
2877
  [
2851
2878
  {
@@ -2868,9 +2895,12 @@ const createMergeableStore = (uniqueId, getNow) => {
2868
2895
  ]);
2869
2896
  }
2870
2897
  };
2871
- const valueChanged = (valueId, newValue) => {
2898
+ const valueChanged = (valueId, newValue, mutating) => {
2872
2899
  setAdd(touchedValues, valueId);
2873
- if (listeningToRawStoreChanges) {
2900
+ if (listeningToRawStoreChanges || mutating) {
2901
+ if (mutating) {
2902
+ mutated = 1;
2903
+ }
2874
2904
  mergeContentOrChanges([
2875
2905
  [{}],
2876
2906
  [
@@ -3088,6 +3118,11 @@ const createMergeableStore = (uniqueId, getNow) => {
3088
3118
  mergeableStore2.applyMergeableChanges(mergeableChanges);
3089
3119
  return applyMergeableChanges(mergeableChanges2);
3090
3120
  };
3121
+ const hadMutated = () => {
3122
+ const result = mutated;
3123
+ mutated = 0;
3124
+ return result;
3125
+ };
3091
3126
  const mergeableStore = {
3092
3127
  getMergeableContent,
3093
3128
  getMergeableContentHashes,
@@ -3104,6 +3139,8 @@ const createMergeableStore = (uniqueId, getNow) => {
3104
3139
  getTransactionMergeableChanges,
3105
3140
  applyMergeableChanges,
3106
3141
  merge,
3142
+ // only used internally by other modules
3143
+ hadMutated,
3107
3144
  };
3108
3145
  store.setInternalListeners(
3109
3146
  preStartTransaction,
@@ -3407,6 +3444,11 @@ const createCustomPersister = (
3407
3444
  ? store.applyChanges
3408
3445
  : store.setContent)(contentOrChanges);
3409
3446
  };
3447
+ const saveAfterMutated = async () => {
3448
+ if (isAutoSaving() && store.hadMutated?.()) {
3449
+ await save();
3450
+ }
3451
+ };
3410
3452
  const load = async (initialContent) => {
3411
3453
  /* istanbul ignore else */
3412
3454
  if (status != 2 /* Saving */) {
@@ -3431,6 +3473,7 @@ const createCustomPersister = (
3431
3473
  },
3432
3474
  );
3433
3475
  setStatus(0 /* Idle */);
3476
+ await saveAfterMutated();
3434
3477
  });
3435
3478
  }
3436
3479
  return persister;
@@ -3449,6 +3492,7 @@ const createCustomPersister = (
3449
3492
  loads++;
3450
3493
  setContentOrChanges(changes ?? content);
3451
3494
  setStatus(0 /* Idle */);
3495
+ await saveAfterMutated();
3452
3496
  }
3453
3497
  } else {
3454
3498
  await load();
@@ -4958,13 +5002,17 @@ const SET_CHANGES = 's';
4958
5002
  const STORE_PATH = '/store';
4959
5003
  const PUT = 'PUT';
4960
5004
  const construct = (prefix, type, payload) =>
4961
- prefix + type + (isString(payload) ? payload : jsonStringWithMap(payload));
5005
+ prefix +
5006
+ type +
5007
+ (isString(payload) ? payload : jsonStringWithUndefined(payload));
4962
5008
  const deconstruct = (prefix, message, stringified) => {
4963
5009
  const prefixSize = size(prefix);
4964
5010
  return strStartsWith(message, prefix)
4965
5011
  ? [
4966
5012
  message[prefixSize],
4967
- (stringified ? jsonParse : String)(slice(message, prefixSize + 1)),
5013
+ (stringified ? jsonParseWithUndefined : String)(
5014
+ slice(message, prefixSize + 1),
5015
+ ),
4968
5016
  ]
4969
5017
  : void 0;
4970
5018
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tinybase",
3
- "version": "7.3.2",
3
+ "version": "7.3.4",
4
4
  "author": "jamesgpearce",
5
5
  "repository": "github:tinyplex/tinybase",
6
6
  "license": "MIT",
@@ -22,31 +22,31 @@
22
22
  "sideEffects": false,
23
23
  "peerDependencies": {
24
24
  "@automerge/automerge-repo": "^2.5.1",
25
- "@cloudflare/workers-types": "^4.20260120.0",
25
+ "@cloudflare/workers-types": "^4.20260214.0",
26
26
  "@electric-sql/pglite": "^0.3.15",
27
27
  "@libsql/client": "^0.17.0",
28
- "@powersync/common": "^1.45.0",
29
- "@sinclair/typebox": "^0.34.47",
30
- "@sqlite.org/sqlite-wasm": "^3.50.4-build1",
28
+ "@powersync/common": "^1.46.0",
29
+ "@sinclair/typebox": "^0.34.48",
30
+ "@sqlite.org/sqlite-wasm": "^3.51.2-build6",
31
31
  "@vlcn.io/crsqlite-wasm": "^0.16.0",
32
32
  "arktype": "^2.1.29",
33
- "bun": "^1.3.6",
34
- "effect": "^3.19.14",
33
+ "bun": "^1.3.9",
34
+ "effect": "^3.19.17",
35
35
  "electric-sql": "^0.12.1",
36
- "expo": "^54.0.31",
36
+ "expo": "^54.0.33",
37
37
  "expo-sqlite": "^16.0.10",
38
38
  "partykit": "^0.0.115",
39
- "partysocket": "^1.1.10",
39
+ "partysocket": "^1.1.13",
40
40
  "postgres": "^3.4.8",
41
- "react": "^19.2.3",
42
- "react-dom": "^19.2.3",
43
- "react-native-mmkv": "4.1.1",
41
+ "react": "^19.2.4",
42
+ "react-dom": "^19.2.4",
43
+ "react-native-mmkv": "4.1.2",
44
44
  "react-native-sqlite-storage": "^6.0.1",
45
45
  "sqlite3": "^5.1.7",
46
46
  "valibot": "^1.2.0",
47
47
  "ws": "^8.19.0",
48
48
  "yjs": "^13.6.29",
49
- "zod": "^4.3.5"
49
+ "zod": "^4.3.6"
50
50
  },
51
51
  "peerDependenciesMeta": {
52
52
  "@automerge/automerge-repo": {
@@ -94,21 +94,22 @@ const objValues = (obj) => object.values(obj);
94
94
  const objSize = (obj) => size(objIds(obj));
95
95
  const objIsEmpty = (obj) => isObject(obj) && objSize(obj) == 0;
96
96
 
97
- const mapNew = (entries) => new Map(entries);
98
- const mapGet = (map, key) => map?.get(key);
99
- const mapForEach = (map, cb) =>
100
- collForEach(map, (value, key) => cb(key, value));
97
+ const map = Map;
98
+ const mapNew = (entries) => new map(entries);
99
+ const mapGet = (map2, key) => map2?.get(key);
100
+ const mapForEach = (map2, cb) =>
101
+ collForEach(map2, (value, key) => cb(key, value));
101
102
  const mapMap = (coll, cb) =>
102
103
  arrayMap([...(coll?.entries() ?? [])], ([key, value]) => cb(value, key));
103
- const mapSet = (map, key, value) =>
104
- isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
105
- const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
106
- if (!collHas(map, key)) {
107
- mapSet(map, key, getDefaultValue());
104
+ const mapSet = (map2, key, value) =>
105
+ isUndefined(value) ? (collDel(map2, key), map2) : map2?.set(key, value);
106
+ const mapEnsure = (map2, key, getDefaultValue, hadExistingValue) => {
107
+ if (!collHas(map2, key)) {
108
+ mapSet(map2, key, getDefaultValue());
108
109
  } else {
109
- hadExistingValue?.(mapGet(map, key));
110
+ hadExistingValue?.(mapGet(map2, key));
110
111
  }
111
- return mapGet(map, key);
112
+ return mapGet(map2, key);
112
113
  };
113
114
  const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
114
115
  ifNotUndefined(
@@ -320,6 +321,11 @@ const createCustomPersister = (
320
321
  ? store.applyChanges
321
322
  : store.setContent)(contentOrChanges);
322
323
  };
324
+ const saveAfterMutated = async () => {
325
+ if (isAutoSaving() && store.hadMutated?.()) {
326
+ await save();
327
+ }
328
+ };
323
329
  const load = async (initialContent) => {
324
330
  /* istanbul ignore else */
325
331
  if (status != 2 /* Saving */) {
@@ -344,6 +350,7 @@ const createCustomPersister = (
344
350
  },
345
351
  );
346
352
  setStatus(0 /* Idle */);
353
+ await saveAfterMutated();
347
354
  });
348
355
  }
349
356
  return persister;
@@ -362,6 +369,7 @@ const createCustomPersister = (
362
369
  loads++;
363
370
  setContentOrChanges(changes ?? content);
364
371
  setStatus(0 /* Idle */);
372
+ await saveAfterMutated();
365
373
  }
366
374
  } else {
367
375
  await load();
@@ -479,7 +487,16 @@ const jsonParse = JSON.parse;
479
487
  const jsonStringWithUndefined = (obj) =>
480
488
  jsonString(obj, (_key, value) => (isUndefined(value) ? UNDEFINED : value));
481
489
  const jsonParseWithUndefined = (str) =>
482
- jsonParse(str, (_key, value) => (value === UNDEFINED ? void 0 : value));
490
+ // JSON.parse reviver removes properties with undefined values
491
+ replaceUndefinedString(jsonParse(str));
492
+ const replaceUndefinedString = (obj) =>
493
+ obj === UNDEFINED
494
+ ? void 0
495
+ : isArray(obj)
496
+ ? arrayMap(obj, replaceUndefinedString)
497
+ : isObject(obj)
498
+ ? objMap(obj, replaceUndefinedString)
499
+ : obj;
483
500
 
484
501
  const textEncoder = /* @__PURE__ */ new GLOBAL.TextEncoder();
485
502
  const getHash = (string) => {
@@ -71,17 +71,18 @@ const collIsEmpty = (coll) => isUndefined(coll) || collSize(coll) == 0;
71
71
  const collForEach = (coll, cb) => coll?.forEach(cb);
72
72
  const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
73
73
 
74
- const mapNew = (entries) => new Map(entries);
75
- const mapGet = (map, key) => map?.get(key);
76
- const mapSet = (map, key, value) =>
77
- isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
78
- const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
79
- if (!collHas(map, key)) {
80
- mapSet(map, key, getDefaultValue());
74
+ const map = Map;
75
+ const mapNew = (entries) => new map(entries);
76
+ const mapGet = (map2, key) => map2?.get(key);
77
+ const mapSet = (map2, key, value) =>
78
+ isUndefined(value) ? (collDel(map2, key), map2) : map2?.set(key, value);
79
+ const mapEnsure = (map2, key, getDefaultValue, hadExistingValue) => {
80
+ if (!collHas(map2, key)) {
81
+ mapSet(map2, key, getDefaultValue());
81
82
  } else {
82
- hadExistingValue?.(mapGet(map, key));
83
+ hadExistingValue?.(mapGet(map2, key));
83
84
  }
84
- return mapGet(map, key);
85
+ return mapGet(map2, key);
85
86
  };
86
87
  const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
87
88
  ifNotUndefined(
@@ -283,6 +284,11 @@ const createCustomPersister = (
283
284
  ? store.applyChanges
284
285
  : store.setContent)(contentOrChanges);
285
286
  };
287
+ const saveAfterMutated = async () => {
288
+ if (isAutoSaving() && store.hadMutated?.()) {
289
+ await save();
290
+ }
291
+ };
286
292
  const load = async (initialContent) => {
287
293
  /* istanbul ignore else */
288
294
  if (status != 2 /* Saving */) {
@@ -307,6 +313,7 @@ const createCustomPersister = (
307
313
  },
308
314
  );
309
315
  setStatus(0 /* Idle */);
316
+ await saveAfterMutated();
310
317
  });
311
318
  }
312
319
  return persister;
@@ -325,6 +332,7 @@ const createCustomPersister = (
325
332
  loads++;
326
333
  setContentOrChanges(changes ?? content);
327
334
  setStatus(0 /* Idle */);
335
+ await saveAfterMutated();
328
336
  }
329
337
  } else {
330
338
  await load();
@@ -71,17 +71,18 @@ const collIsEmpty = (coll) => isUndefined(coll) || collSize(coll) == 0;
71
71
  const collForEach = (coll, cb) => coll?.forEach(cb);
72
72
  const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
73
73
 
74
- const mapNew = (entries) => new Map(entries);
75
- const mapGet = (map, key) => map?.get(key);
76
- const mapSet = (map, key, value) =>
77
- isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
78
- const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
79
- if (!collHas(map, key)) {
80
- mapSet(map, key, getDefaultValue());
74
+ const map = Map;
75
+ const mapNew = (entries) => new map(entries);
76
+ const mapGet = (map2, key) => map2?.get(key);
77
+ const mapSet = (map2, key, value) =>
78
+ isUndefined(value) ? (collDel(map2, key), map2) : map2?.set(key, value);
79
+ const mapEnsure = (map2, key, getDefaultValue, hadExistingValue) => {
80
+ if (!collHas(map2, key)) {
81
+ mapSet(map2, key, getDefaultValue());
81
82
  } else {
82
- hadExistingValue?.(mapGet(map, key));
83
+ hadExistingValue?.(mapGet(map2, key));
83
84
  }
84
- return mapGet(map, key);
85
+ return mapGet(map2, key);
85
86
  };
86
87
  const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
87
88
  ifNotUndefined(
@@ -283,6 +284,11 @@ const createCustomPersister = (
283
284
  ? store.applyChanges
284
285
  : store.setContent)(contentOrChanges);
285
286
  };
287
+ const saveAfterMutated = async () => {
288
+ if (isAutoSaving() && store.hadMutated?.()) {
289
+ await save();
290
+ }
291
+ };
286
292
  const load = async (initialContent) => {
287
293
  /* istanbul ignore else */
288
294
  if (status != 2 /* Saving */) {
@@ -307,6 +313,7 @@ const createCustomPersister = (
307
313
  },
308
314
  );
309
315
  setStatus(0 /* Idle */);
316
+ await saveAfterMutated();
310
317
  });
311
318
  }
312
319
  return persister;
@@ -325,6 +332,7 @@ const createCustomPersister = (
325
332
  loads++;
326
333
  setContentOrChanges(changes ?? content);
327
334
  setStatus(0 /* Idle */);
335
+ await saveAfterMutated();
328
336
  }
329
337
  } else {
330
338
  await load();