tinybase 8.0.0-beta.0 → 8.0.0-beta.1

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 (264) hide show
  1. package/@types/index.d.ts +1 -0
  2. package/@types/mergeable-store/with-schemas/index.d.ts +1 -1
  3. package/@types/middleware/index.d.ts +1064 -0
  4. package/@types/middleware/with-schemas/index.d.ts +1355 -0
  5. package/@types/omni/index.d.ts +1 -0
  6. package/@types/omni/with-schemas/index.d.ts +1 -0
  7. package/@types/store/index.d.ts +0 -1
  8. package/@types/with-schemas/index.d.ts +1 -0
  9. package/agents.md +33 -11
  10. package/checkpoints/index.js +20 -20
  11. package/checkpoints/with-schemas/index.js +20 -20
  12. package/common/index.js +3 -2
  13. package/common/with-schemas/index.js +3 -2
  14. package/index.js +574 -215
  15. package/indexes/index.js +13 -12
  16. package/indexes/with-schemas/index.js +13 -12
  17. package/mergeable-store/index.js +461 -197
  18. package/mergeable-store/with-schemas/index.js +461 -197
  19. package/metrics/index.js +13 -12
  20. package/metrics/with-schemas/index.js +13 -12
  21. package/middleware/index.js +130 -0
  22. package/middleware/with-schemas/index.js +130 -0
  23. package/min/checkpoints/index.js +1 -1
  24. package/min/checkpoints/index.js.gz +0 -0
  25. package/min/checkpoints/with-schemas/index.js +1 -1
  26. package/min/checkpoints/with-schemas/index.js.gz +0 -0
  27. package/min/common/index.js +1 -1
  28. package/min/common/index.js.gz +0 -0
  29. package/min/common/with-schemas/index.js +1 -1
  30. package/min/common/with-schemas/index.js.gz +0 -0
  31. package/min/index.js +1 -1
  32. package/min/index.js.gz +0 -0
  33. package/min/indexes/index.js +1 -1
  34. package/min/indexes/index.js.gz +0 -0
  35. package/min/indexes/with-schemas/index.js +1 -1
  36. package/min/indexes/with-schemas/index.js.gz +0 -0
  37. package/min/mergeable-store/index.js +1 -1
  38. package/min/mergeable-store/index.js.gz +0 -0
  39. package/min/mergeable-store/with-schemas/index.js +1 -1
  40. package/min/mergeable-store/with-schemas/index.js.gz +0 -0
  41. package/min/metrics/index.js +1 -1
  42. package/min/metrics/index.js.gz +0 -0
  43. package/min/metrics/with-schemas/index.js +1 -1
  44. package/min/metrics/with-schemas/index.js.gz +0 -0
  45. package/min/middleware/index.js +1 -0
  46. package/min/middleware/index.js.gz +0 -0
  47. package/min/middleware/with-schemas/index.js +1 -0
  48. package/min/middleware/with-schemas/index.js.gz +0 -0
  49. package/min/omni/index.js +1 -1
  50. package/min/omni/index.js.gz +0 -0
  51. package/min/omni/with-schemas/index.js +1 -1
  52. package/min/omni/with-schemas/index.js.gz +0 -0
  53. package/min/persisters/index.js +1 -1
  54. package/min/persisters/index.js.gz +0 -0
  55. package/min/persisters/persister-automerge/index.js +1 -1
  56. package/min/persisters/persister-automerge/index.js.gz +0 -0
  57. package/min/persisters/persister-automerge/with-schemas/index.js +1 -1
  58. package/min/persisters/persister-automerge/with-schemas/index.js.gz +0 -0
  59. package/min/persisters/persister-browser/index.js +1 -1
  60. package/min/persisters/persister-browser/index.js.gz +0 -0
  61. package/min/persisters/persister-browser/with-schemas/index.js +1 -1
  62. package/min/persisters/persister-browser/with-schemas/index.js.gz +0 -0
  63. package/min/persisters/persister-cr-sqlite-wasm/index.js +1 -1
  64. package/min/persisters/persister-cr-sqlite-wasm/index.js.gz +0 -0
  65. package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +1 -1
  66. package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js.gz +0 -0
  67. package/min/persisters/persister-durable-object-sql-storage/index.js +1 -1
  68. package/min/persisters/persister-durable-object-sql-storage/index.js.gz +0 -0
  69. package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js +1 -1
  70. package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js.gz +0 -0
  71. package/min/persisters/persister-durable-object-storage/index.js +1 -1
  72. package/min/persisters/persister-durable-object-storage/index.js.gz +0 -0
  73. package/min/persisters/persister-durable-object-storage/with-schemas/index.js +1 -1
  74. package/min/persisters/persister-durable-object-storage/with-schemas/index.js.gz +0 -0
  75. package/min/persisters/persister-electric-sql/index.js +1 -1
  76. package/min/persisters/persister-electric-sql/index.js.gz +0 -0
  77. package/min/persisters/persister-electric-sql/with-schemas/index.js +1 -1
  78. package/min/persisters/persister-electric-sql/with-schemas/index.js.gz +0 -0
  79. package/min/persisters/persister-expo-sqlite/index.js +1 -1
  80. package/min/persisters/persister-expo-sqlite/index.js.gz +0 -0
  81. package/min/persisters/persister-expo-sqlite/with-schemas/index.js +1 -1
  82. package/min/persisters/persister-expo-sqlite/with-schemas/index.js.gz +0 -0
  83. package/min/persisters/persister-file/index.js +1 -1
  84. package/min/persisters/persister-file/index.js.gz +0 -0
  85. package/min/persisters/persister-file/with-schemas/index.js +1 -1
  86. package/min/persisters/persister-file/with-schemas/index.js.gz +0 -0
  87. package/min/persisters/persister-indexed-db/index.js +1 -1
  88. package/min/persisters/persister-indexed-db/index.js.gz +0 -0
  89. package/min/persisters/persister-indexed-db/with-schemas/index.js +1 -1
  90. package/min/persisters/persister-indexed-db/with-schemas/index.js.gz +0 -0
  91. package/min/persisters/persister-libsql/index.js +1 -1
  92. package/min/persisters/persister-libsql/index.js.gz +0 -0
  93. package/min/persisters/persister-libsql/with-schemas/index.js +1 -1
  94. package/min/persisters/persister-libsql/with-schemas/index.js.gz +0 -0
  95. package/min/persisters/persister-partykit-client/index.js +1 -1
  96. package/min/persisters/persister-partykit-client/index.js.gz +0 -0
  97. package/min/persisters/persister-partykit-client/with-schemas/index.js +1 -1
  98. package/min/persisters/persister-partykit-client/with-schemas/index.js.gz +0 -0
  99. package/min/persisters/persister-partykit-server/index.js +1 -1
  100. package/min/persisters/persister-partykit-server/index.js.gz +0 -0
  101. package/min/persisters/persister-partykit-server/with-schemas/index.js +1 -1
  102. package/min/persisters/persister-partykit-server/with-schemas/index.js.gz +0 -0
  103. package/min/persisters/persister-pglite/index.js +1 -1
  104. package/min/persisters/persister-pglite/index.js.gz +0 -0
  105. package/min/persisters/persister-pglite/with-schemas/index.js +1 -1
  106. package/min/persisters/persister-pglite/with-schemas/index.js.gz +0 -0
  107. package/min/persisters/persister-postgres/index.js +1 -1
  108. package/min/persisters/persister-postgres/index.js.gz +0 -0
  109. package/min/persisters/persister-postgres/with-schemas/index.js +1 -1
  110. package/min/persisters/persister-postgres/with-schemas/index.js.gz +0 -0
  111. package/min/persisters/persister-powersync/index.js +1 -1
  112. package/min/persisters/persister-powersync/index.js.gz +0 -0
  113. package/min/persisters/persister-powersync/with-schemas/index.js +1 -1
  114. package/min/persisters/persister-powersync/with-schemas/index.js.gz +0 -0
  115. package/min/persisters/persister-react-native-mmkv/index.js +1 -1
  116. package/min/persisters/persister-react-native-mmkv/index.js.gz +0 -0
  117. package/min/persisters/persister-react-native-mmkv/with-schemas/index.js +1 -1
  118. package/min/persisters/persister-react-native-mmkv/with-schemas/index.js.gz +0 -0
  119. package/min/persisters/persister-react-native-sqlite/index.js +1 -1
  120. package/min/persisters/persister-react-native-sqlite/index.js.gz +0 -0
  121. package/min/persisters/persister-react-native-sqlite/with-schemas/index.js +1 -1
  122. package/min/persisters/persister-react-native-sqlite/with-schemas/index.js.gz +0 -0
  123. package/min/persisters/persister-remote/index.js +1 -1
  124. package/min/persisters/persister-remote/index.js.gz +0 -0
  125. package/min/persisters/persister-remote/with-schemas/index.js +1 -1
  126. package/min/persisters/persister-remote/with-schemas/index.js.gz +0 -0
  127. package/min/persisters/persister-sqlite-bun/index.js +1 -1
  128. package/min/persisters/persister-sqlite-bun/index.js.gz +0 -0
  129. package/min/persisters/persister-sqlite-bun/with-schemas/index.js +1 -1
  130. package/min/persisters/persister-sqlite-bun/with-schemas/index.js.gz +0 -0
  131. package/min/persisters/persister-sqlite-wasm/index.js +1 -1
  132. package/min/persisters/persister-sqlite-wasm/index.js.gz +0 -0
  133. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js +1 -1
  134. package/min/persisters/persister-sqlite-wasm/with-schemas/index.js.gz +0 -0
  135. package/min/persisters/persister-sqlite3/index.js +1 -1
  136. package/min/persisters/persister-sqlite3/index.js.gz +0 -0
  137. package/min/persisters/persister-sqlite3/with-schemas/index.js +1 -1
  138. package/min/persisters/persister-sqlite3/with-schemas/index.js.gz +0 -0
  139. package/min/persisters/persister-yjs/index.js +1 -1
  140. package/min/persisters/persister-yjs/index.js.gz +0 -0
  141. package/min/persisters/persister-yjs/with-schemas/index.js +1 -1
  142. package/min/persisters/persister-yjs/with-schemas/index.js.gz +0 -0
  143. package/min/persisters/with-schemas/index.js +1 -1
  144. package/min/persisters/with-schemas/index.js.gz +0 -0
  145. package/min/queries/index.js +1 -1
  146. package/min/queries/index.js.gz +0 -0
  147. package/min/queries/with-schemas/index.js +1 -1
  148. package/min/queries/with-schemas/index.js.gz +0 -0
  149. package/min/relationships/index.js +1 -1
  150. package/min/relationships/index.js.gz +0 -0
  151. package/min/relationships/with-schemas/index.js +1 -1
  152. package/min/relationships/with-schemas/index.js.gz +0 -0
  153. package/min/store/index.js +1 -1
  154. package/min/store/index.js.gz +0 -0
  155. package/min/store/with-schemas/index.js +1 -1
  156. package/min/store/with-schemas/index.js.gz +0 -0
  157. package/min/synchronizers/index.js +1 -1
  158. package/min/synchronizers/index.js.gz +0 -0
  159. package/min/synchronizers/synchronizer-broadcast-channel/index.js +1 -1
  160. package/min/synchronizers/synchronizer-broadcast-channel/index.js.gz +0 -0
  161. package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +1 -1
  162. package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js.gz +0 -0
  163. package/min/synchronizers/synchronizer-local/index.js +1 -1
  164. package/min/synchronizers/synchronizer-local/index.js.gz +0 -0
  165. package/min/synchronizers/synchronizer-local/with-schemas/index.js +1 -1
  166. package/min/synchronizers/synchronizer-local/with-schemas/index.js.gz +0 -0
  167. package/min/synchronizers/synchronizer-ws-client/index.js +1 -1
  168. package/min/synchronizers/synchronizer-ws-client/index.js.gz +0 -0
  169. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js +1 -1
  170. package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js.gz +0 -0
  171. package/min/synchronizers/synchronizer-ws-server/index.js +1 -1
  172. package/min/synchronizers/synchronizer-ws-server/index.js.gz +0 -0
  173. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js +1 -1
  174. package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js.gz +0 -0
  175. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js +1 -1
  176. package/min/synchronizers/synchronizer-ws-server-durable-object/index.js.gz +0 -0
  177. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +1 -1
  178. package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js.gz +0 -0
  179. package/min/synchronizers/synchronizer-ws-server-simple/index.js +1 -1
  180. package/min/synchronizers/synchronizer-ws-server-simple/index.js.gz +0 -0
  181. package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +1 -1
  182. package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js.gz +0 -0
  183. package/min/synchronizers/with-schemas/index.js +1 -1
  184. package/min/synchronizers/with-schemas/index.js.gz +0 -0
  185. package/min/ui-react-inspector/index.js +1 -1
  186. package/min/ui-react-inspector/index.js.gz +0 -0
  187. package/min/ui-react-inspector/with-schemas/index.js +1 -1
  188. package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
  189. package/min/with-schemas/index.js +1 -1
  190. package/min/with-schemas/index.js.gz +0 -0
  191. package/omni/index.js +610 -232
  192. package/omni/with-schemas/index.js +610 -232
  193. package/package.json +55 -19
  194. package/persisters/index.js +29 -12
  195. package/persisters/persister-automerge/index.js +17 -9
  196. package/persisters/persister-automerge/with-schemas/index.js +17 -9
  197. package/persisters/persister-browser/index.js +34 -10
  198. package/persisters/persister-browser/with-schemas/index.js +34 -10
  199. package/persisters/persister-cr-sqlite-wasm/index.js +29 -12
  200. package/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +29 -12
  201. package/persisters/persister-durable-object-sql-storage/index.js +29 -12
  202. package/persisters/persister-durable-object-sql-storage/with-schemas/index.js +29 -12
  203. package/persisters/persister-durable-object-storage/index.js +24 -17
  204. package/persisters/persister-durable-object-storage/with-schemas/index.js +24 -17
  205. package/persisters/persister-electric-sql/index.js +29 -12
  206. package/persisters/persister-electric-sql/with-schemas/index.js +29 -12
  207. package/persisters/persister-expo-sqlite/index.js +29 -12
  208. package/persisters/persister-expo-sqlite/with-schemas/index.js +29 -12
  209. package/persisters/persister-file/index.js +34 -10
  210. package/persisters/persister-file/with-schemas/index.js +34 -10
  211. package/persisters/persister-indexed-db/index.js +17 -9
  212. package/persisters/persister-indexed-db/with-schemas/index.js +17 -9
  213. package/persisters/persister-libsql/index.js +29 -12
  214. package/persisters/persister-libsql/with-schemas/index.js +29 -12
  215. package/persisters/persister-partykit-client/index.js +44 -11
  216. package/persisters/persister-partykit-client/with-schemas/index.js +44 -11
  217. package/persisters/persister-partykit-server/index.js +39 -4
  218. package/persisters/persister-partykit-server/with-schemas/index.js +39 -4
  219. package/persisters/persister-pglite/index.js +29 -12
  220. package/persisters/persister-pglite/with-schemas/index.js +29 -12
  221. package/persisters/persister-postgres/index.js +29 -12
  222. package/persisters/persister-postgres/with-schemas/index.js +29 -12
  223. package/persisters/persister-powersync/index.js +29 -12
  224. package/persisters/persister-powersync/with-schemas/index.js +29 -12
  225. package/persisters/persister-react-native-mmkv/index.js +17 -9
  226. package/persisters/persister-react-native-mmkv/with-schemas/index.js +17 -9
  227. package/persisters/persister-react-native-sqlite/index.js +29 -12
  228. package/persisters/persister-react-native-sqlite/with-schemas/index.js +29 -12
  229. package/persisters/persister-remote/index.js +17 -9
  230. package/persisters/persister-remote/with-schemas/index.js +17 -9
  231. package/persisters/persister-sqlite-bun/index.js +29 -12
  232. package/persisters/persister-sqlite-bun/with-schemas/index.js +29 -12
  233. package/persisters/persister-sqlite-wasm/index.js +29 -12
  234. package/persisters/persister-sqlite-wasm/with-schemas/index.js +29 -12
  235. package/persisters/persister-sqlite3/index.js +29 -12
  236. package/persisters/persister-sqlite3/with-schemas/index.js +29 -12
  237. package/persisters/persister-yjs/index.js +19 -11
  238. package/persisters/persister-yjs/with-schemas/index.js +19 -11
  239. package/persisters/with-schemas/index.js +29 -12
  240. package/queries/index.js +16 -20
  241. package/queries/with-schemas/index.js +16 -20
  242. package/readme.md +21 -13
  243. package/relationships/index.js +13 -12
  244. package/relationships/with-schemas/index.js +13 -12
  245. package/releases.md +41 -41
  246. package/store/index.js +442 -192
  247. package/store/with-schemas/index.js +442 -192
  248. package/synchronizers/index.js +17 -9
  249. package/synchronizers/synchronizer-broadcast-channel/index.js +17 -9
  250. package/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +17 -9
  251. package/synchronizers/synchronizer-local/index.js +19 -11
  252. package/synchronizers/synchronizer-local/with-schemas/index.js +19 -11
  253. package/synchronizers/synchronizer-ws-client/index.js +31 -10
  254. package/synchronizers/synchronizer-ws-client/with-schemas/index.js +31 -10
  255. package/synchronizers/synchronizer-ws-server/index.js +34 -13
  256. package/synchronizers/synchronizer-ws-server/with-schemas/index.js +34 -13
  257. package/synchronizers/synchronizer-ws-server-durable-object/index.js +31 -10
  258. package/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +31 -10
  259. package/synchronizers/synchronizer-ws-server-simple/index.js +11 -10
  260. package/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +11 -10
  261. package/synchronizers/with-schemas/index.js +17 -9
  262. package/ui-react-inspector/index.js +438 -193
  263. package/ui-react-inspector/with-schemas/index.js +438 -193
  264. package/with-schemas/index.js +574 -215
@@ -101,6 +101,7 @@ const size = (arrayOrString) => arrayOrString.length;
101
101
  const test = (regex, subject) => regex.test(subject);
102
102
  const getUndefined = () => void 0;
103
103
  const getArg = (value) => value;
104
+ const structuredClone = GLOBAL.structuredClone;
104
105
  const errorNew = (message) => {
105
106
  throw new Error(message);
106
107
  };
@@ -212,7 +213,16 @@ const jsonStringWithMap = (obj) =>
212
213
  const jsonStringWithUndefined = (obj) =>
213
214
  jsonString(obj, (_key, value) => (isUndefined(value) ? UNDEFINED : value));
214
215
  const jsonParseWithUndefined = (str) =>
215
- jsonParse(str, (_key, value) => (value === UNDEFINED ? void 0 : value));
216
+ // JSON.parse reviver removes properties with undefined values
217
+ replaceUndefinedString(jsonParse(str));
218
+ const replaceUndefinedString = (obj) =>
219
+ obj === UNDEFINED
220
+ ? void 0
221
+ : isArray(obj)
222
+ ? arrayMap(obj, replaceUndefinedString)
223
+ : isObject(obj)
224
+ ? objMap(obj, replaceUndefinedString)
225
+ : obj;
216
226
 
217
227
  const collSizeN = (collSizer) => (coll) =>
218
228
  arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
@@ -227,31 +237,32 @@ const collClear = (coll) => coll.clear();
227
237
  const collForEach = (coll, cb) => coll?.forEach(cb);
228
238
  const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
229
239
 
230
- const mapNew = (entries) => new Map(entries);
231
- const mapKeys = (map) => [...(map?.keys() ?? [])];
232
- const mapGet = (map, key) => map?.get(key);
233
- const mapForEach = (map, cb) =>
234
- collForEach(map, (value, key) => cb(key, value));
240
+ const map = Map;
241
+ const mapNew = (entries) => new map(entries);
242
+ const mapKeys = (map2) => [...(map2?.keys() ?? [])];
243
+ const mapGet = (map2, key) => map2?.get(key);
244
+ const mapForEach = (map2, cb) =>
245
+ collForEach(map2, (value, key) => cb(key, value));
235
246
  const mapMap = (coll, cb) =>
236
247
  arrayMap([...(coll?.entries() ?? [])], ([key, value]) => cb(value, key));
237
- const mapSet = (map, key, value) =>
238
- isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
239
- const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
240
- if (!collHas(map, key)) {
241
- mapSet(map, key, getDefaultValue());
248
+ const mapSet = (map2, key, value) =>
249
+ isUndefined(value) ? (collDel(map2, key), map2) : map2?.set(key, value);
250
+ const mapEnsure = (map2, key, getDefaultValue, hadExistingValue) => {
251
+ if (!collHas(map2, key)) {
252
+ mapSet(map2, key, getDefaultValue());
242
253
  } else {
243
- hadExistingValue?.(mapGet(map, key));
254
+ hadExistingValue?.(mapGet(map2, key));
244
255
  }
245
- return mapGet(map, key);
256
+ return mapGet(map2, key);
246
257
  };
247
- const mapMatch = (map, obj, set, del = mapSet) => {
248
- objMap(obj, (value, id) => set(map, id, value));
249
- mapForEach(map, (id) => (objHas(obj, id) ? 0 : del(map, id)));
250
- return map;
258
+ const mapMatch = (map2, obj, set, del = mapSet) => {
259
+ objMap(obj, (value, id) => set(map2, id, value));
260
+ mapForEach(map2, (id) => (objHas(obj, id) ? 0 : del(map2, id)));
261
+ return map2;
251
262
  };
252
- const mapToObj = (map, valueMapper, excludeMapValue, excludeObjValue) => {
263
+ const mapToObj = (map2, valueMapper, excludeMapValue, excludeObjValue) => {
253
264
  const obj = {};
254
- collForEach(map, (mapValue, id) => {
265
+ collForEach(map2, (mapValue, id) => {
255
266
  if (!excludeMapValue?.(mapValue, id)) {
256
267
  const objValue = valueMapper ? valueMapper(mapValue, id) : mapValue;
257
268
  if (!excludeObjValue?.(objValue)) {
@@ -261,27 +272,27 @@ const mapToObj = (map, valueMapper, excludeMapValue, excludeObjValue) => {
261
272
  });
262
273
  return obj;
263
274
  };
264
- const mapToObj2 = (map, valueMapper, excludeMapValue) =>
275
+ const mapToObj2 = (map2, valueMapper, excludeMapValue) =>
265
276
  mapToObj(
266
- map,
277
+ map2,
267
278
  (childMap) => mapToObj(childMap, valueMapper, excludeMapValue),
268
279
  collIsEmpty,
269
280
  objIsEmpty,
270
281
  );
271
- const mapToObj3 = (map, valueMapper, excludeMapValue) =>
282
+ const mapToObj3 = (map2, valueMapper, excludeMapValue) =>
272
283
  mapToObj(
273
- map,
284
+ map2,
274
285
  (childMap) => mapToObj2(childMap, valueMapper, excludeMapValue),
275
286
  collIsEmpty,
276
287
  objIsEmpty,
277
288
  );
278
- const mapClone = (map, mapValue) => {
279
- const map2 = mapNew();
280
- collForEach(map, (value, key) => map2.set(key, mapValue?.(value) ?? value));
281
- return map2;
289
+ const mapClone = (map2, mapValue) => {
290
+ const map22 = mapNew();
291
+ collForEach(map2, (value, key) => map22.set(key, mapValue?.(value) ?? value));
292
+ return map22;
282
293
  };
283
- const mapClone2 = (map) => mapClone(map, mapClone);
284
- const mapClone3 = (map) => mapClone(map, mapClone2);
294
+ const mapClone2 = (map2) => mapClone(map2, mapClone);
295
+ const mapClone3 = (map2) => mapClone(map2, mapClone2);
285
296
  const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
286
297
  ifNotUndefined(
287
298
  (ensureLeaf ? mapEnsure : mapGet)(
@@ -482,6 +493,11 @@ const createCustomPersister = (
482
493
  ? store.applyChanges
483
494
  : store.setContent)(contentOrChanges);
484
495
  };
496
+ const saveAfterMutated = async () => {
497
+ if (isAutoSaving() && store.hadMutated?.()) {
498
+ await save();
499
+ }
500
+ };
485
501
  const load = async (initialContent) => {
486
502
  /* istanbul ignore else */
487
503
  if (status != 2 /* Saving */) {
@@ -506,6 +522,7 @@ const createCustomPersister = (
506
522
  },
507
523
  );
508
524
  setStatus(0 /* Idle */);
525
+ await saveAfterMutated();
509
526
  });
510
527
  }
511
528
  return persister;
@@ -524,6 +541,7 @@ const createCustomPersister = (
524
541
  loads++;
525
542
  setContentOrChanges(changes ?? content);
526
543
  setStatus(0 /* Idle */);
544
+ await saveAfterMutated();
527
545
  }
528
546
  } else {
529
547
  await load();
@@ -686,12 +704,6 @@ const getCellOrValueType = (cellOrValue) => {
686
704
  ? type
687
705
  : void 0;
688
706
  };
689
- const setOrDelCell = (store, tableId, rowId, cellId, cell) =>
690
- isUndefined(cell)
691
- ? store.delCell(tableId, rowId, cellId, true)
692
- : store.setCell(tableId, rowId, cellId, cell);
693
- const setOrDelValue = (store, valueId, value) =>
694
- isUndefined(value) ? store.delValue(valueId) : store.setValue(valueId, value);
695
707
  const getTypeCase = (type, stringCase, numberCase, booleanCase) =>
696
708
  type == STRING
697
709
  ? stringCase
@@ -716,13 +728,17 @@ const idsChanged = (changedIds, id2, addedOrRemoved) =>
716
728
  id2,
717
729
  mapGet(changedIds, id2) == -addedOrRemoved ? void 0 : addedOrRemoved,
718
730
  );
731
+ const contentOrChangesIsEqual = ([tables1, values1], [tables2, values2]) =>
732
+ objIsEqual(tables1, tables2) && objIsEqual(values1, values2);
719
733
  const createStore = () => {
720
734
  let hasTablesSchema;
721
735
  let hasValuesSchema;
722
736
  let hadTables = false;
723
737
  let hadValues = false;
724
738
  let transactions = 0;
739
+ let middleware = [];
725
740
  let internalListeners = [];
741
+ let mutating = 0;
726
742
  const changedTableIds = mapNew();
727
743
  const changedTableCellIds = mapNew();
728
744
  const changedRowCount = mapNew();
@@ -768,6 +784,19 @@ const createStore = () => {
768
784
  const finishTransactionListeners = pairNewMap();
769
785
  const [addListener, callListeners, delListenerImpl, callListenerImpl] =
770
786
  getListenerFunctions(() => store);
787
+ const whileMutating = (action) => {
788
+ const wasMutating = mutating;
789
+ mutating = 1;
790
+ const result = action();
791
+ mutating = wasMutating;
792
+ return result;
793
+ };
794
+ const ifTransformed = (snapshot, getResult, then, isEqual = Object.is) =>
795
+ ifNotUndefined(getResult(), (result) =>
796
+ snapshot === result || isEqual(snapshot, result)
797
+ ? then(result)
798
+ : whileMutating(() => then(result)),
799
+ );
771
800
  const validateTablesSchema = (tableSchema) =>
772
801
  objValidate(tableSchema, (tableSchema2) =>
773
802
  objValidate(tableSchema2, validateCellOrValueSchema),
@@ -955,82 +984,194 @@ const createStore = () => {
955
984
  );
956
985
  const setOrDelTables = (tables) =>
957
986
  objIsEmpty(tables) ? delTables() : setTables(tables);
958
- const setValidContent = ([tables, values]) => {
959
- (objIsEmpty(tables) ? delTables : setTables)(tables);
960
- (objIsEmpty(values) ? delValues : setValues)(values);
961
- };
962
- const setValidTables = (tables) =>
963
- mapMatch(
964
- tablesMap,
987
+ const setOrDelCell = (tableId, rowId, cellId, cell, skipMiddleware) =>
988
+ isUndefined(cell)
989
+ ? delCell(tableId, rowId, cellId, true, skipMiddleware)
990
+ : setCell(tableId, rowId, cellId, cell, skipMiddleware);
991
+ const setOrDelValues = (values) =>
992
+ objIsEmpty(values) ? delValues() : setValues(values);
993
+ const setOrDelValue = (valueId, value, skipMiddleware) =>
994
+ isUndefined(value)
995
+ ? delValue(valueId, skipMiddleware)
996
+ : setValue(valueId, value, skipMiddleware);
997
+ const setValidContent = (content) =>
998
+ ifTransformed(
999
+ content,
1000
+ () =>
1001
+ ifNotUndefined(
1002
+ middleware[0],
1003
+ (willSetContent) =>
1004
+ whileMutating(() => willSetContent(structuredClone(content))),
1005
+ () => content,
1006
+ ),
1007
+ ([tables, values]) => {
1008
+ (objIsEmpty(tables) ? delTables : setTables)(tables);
1009
+ (objIsEmpty(values) ? delValues : setValues)(values);
1010
+ },
1011
+ contentOrChangesIsEqual,
1012
+ );
1013
+ const setValidTables = (tables, forceDel) =>
1014
+ ifTransformed(
965
1015
  tables,
966
- (_tables, tableId, table) => setValidTable(tableId, table),
967
- (_tables, tableId) => delValidTable(tableId),
1016
+ () =>
1017
+ forceDel
1018
+ ? tables
1019
+ : ifNotUndefined(
1020
+ middleware[1],
1021
+ (willSetTables) =>
1022
+ whileMutating(() => willSetTables(structuredClone(tables))),
1023
+ () => tables,
1024
+ ),
1025
+ (validTables) =>
1026
+ mapMatch(
1027
+ tablesMap,
1028
+ validTables,
1029
+ (_tables, tableId, table) => setValidTable(tableId, table),
1030
+ (_tables, tableId) => delValidTable(tableId),
1031
+ ),
1032
+ objIsEqual,
968
1033
  );
969
- const setValidTable = (tableId, table) =>
970
- mapMatch(
971
- mapEnsure(tablesMap, tableId, () => {
972
- tableIdsChanged(tableId, 1);
973
- mapSet(tablePoolFunctions, tableId, getPoolFunctions());
974
- mapSet(tableCellIds, tableId, mapNew());
975
- return mapNew();
976
- }),
1034
+ const setValidTable = (tableId, table, forceDel) =>
1035
+ ifTransformed(
977
1036
  table,
978
- (tableMap, rowId, row) => setValidRow(tableId, tableMap, rowId, row),
979
- (tableMap, rowId) => delValidRow(tableId, tableMap, rowId),
1037
+ () =>
1038
+ forceDel
1039
+ ? table
1040
+ : ifNotUndefined(
1041
+ middleware[2],
1042
+ (willSetTable) =>
1043
+ whileMutating(() =>
1044
+ willSetTable(tableId, structuredClone(table)),
1045
+ ),
1046
+ () => table,
1047
+ ),
1048
+ (validTable) =>
1049
+ mapMatch(
1050
+ mapEnsure(tablesMap, tableId, () => {
1051
+ tableIdsChanged(tableId, 1);
1052
+ mapSet(tablePoolFunctions, tableId, getPoolFunctions());
1053
+ mapSet(tableCellIds, tableId, mapNew());
1054
+ return mapNew();
1055
+ }),
1056
+ validTable,
1057
+ (tableMap, rowId, row) => setValidRow(tableId, tableMap, rowId, row),
1058
+ (tableMap, rowId) => delValidRow(tableId, tableMap, rowId),
1059
+ ),
1060
+ objIsEqual,
980
1061
  );
981
1062
  const setValidRow = (tableId, tableMap, rowId, row, forceDel) =>
982
- mapMatch(
983
- mapEnsure(tableMap, rowId, () => {
984
- rowIdsChanged(tableId, rowId, 1);
985
- return mapNew();
986
- }),
1063
+ ifTransformed(
987
1064
  row,
988
- (rowMap, cellId, cell) =>
989
- setValidCell(tableId, rowId, rowMap, cellId, cell),
990
- (rowMap, cellId) =>
991
- delValidCell(tableId, tableMap, rowId, rowMap, cellId, forceDel),
1065
+ () =>
1066
+ forceDel
1067
+ ? row
1068
+ : ifNotUndefined(
1069
+ middleware[3],
1070
+ (willSetRow) =>
1071
+ whileMutating(() =>
1072
+ willSetRow(tableId, rowId, structuredClone(row)),
1073
+ ),
1074
+ () => row,
1075
+ ),
1076
+ (validRow) =>
1077
+ mapMatch(
1078
+ mapEnsure(tableMap, rowId, () => {
1079
+ rowIdsChanged(tableId, rowId, 1);
1080
+ return mapNew();
1081
+ }),
1082
+ validRow,
1083
+ (rowMap, cellId, cell) =>
1084
+ setValidCell(tableId, rowId, rowMap, cellId, cell),
1085
+ (rowMap, cellId) =>
1086
+ delValidCell(tableId, tableMap, rowId, rowMap, cellId, forceDel),
1087
+ ),
1088
+ objIsEqual,
992
1089
  );
993
- const setValidCell = (tableId, rowId, rowMap, cellId, cell) => {
994
- if (!collHas(rowMap, cellId)) {
995
- cellIdsChanged(tableId, rowId, cellId, 1);
996
- }
997
- const oldCell = mapGet(rowMap, cellId);
998
- if (cell !== oldCell) {
999
- cellChanged(tableId, rowId, cellId, oldCell, cell);
1000
- mapSet(rowMap, cellId, cell);
1001
- }
1002
- };
1003
- const setCellIntoDefaultRow = (tableId, tableMap, rowId, cellId, validCell) =>
1090
+ const setValidCell = (tableId, rowId, rowMap, cellId, cell, skipMiddleware) =>
1091
+ ifTransformed(
1092
+ cell,
1093
+ () =>
1094
+ ifNotUndefined(
1095
+ skipMiddleware ? void 0 : middleware[4],
1096
+ (willSetCell) =>
1097
+ whileMutating(() => willSetCell(tableId, rowId, cellId, cell)),
1098
+ () => cell,
1099
+ ),
1100
+ (cell2) => {
1101
+ if (!collHas(rowMap, cellId)) {
1102
+ cellIdsChanged(tableId, rowId, cellId, 1);
1103
+ }
1104
+ const oldCell = mapGet(rowMap, cellId);
1105
+ if (cell2 !== oldCell) {
1106
+ cellChanged(tableId, rowId, cellId, oldCell, cell2);
1107
+ mapSet(rowMap, cellId, cell2);
1108
+ }
1109
+ },
1110
+ );
1111
+ const setCellIntoNewRow = (
1112
+ tableId,
1113
+ tableMap,
1114
+ rowId,
1115
+ cellId,
1116
+ validCell,
1117
+ skipMiddleware,
1118
+ ) =>
1004
1119
  ifNotUndefined(
1005
1120
  mapGet(tableMap, rowId),
1006
- (rowMap) => setValidCell(tableId, rowId, rowMap, cellId, validCell),
1007
- () =>
1008
- setValidRow(
1009
- tableId,
1010
- tableMap,
1011
- rowId,
1121
+ (rowMap) =>
1122
+ setValidCell(tableId, rowId, rowMap, cellId, validCell, skipMiddleware),
1123
+ () => {
1124
+ const rowMap = mapNew();
1125
+ mapSet(tableMap, rowId, rowMap);
1126
+ rowIdsChanged(tableId, rowId, 1);
1127
+ objMap(
1012
1128
  addDefaultsToRow({[cellId]: validCell}, tableId, rowId),
1013
- ),
1129
+ (cell, cellId2) =>
1130
+ setValidCell(tableId, rowId, rowMap, cellId2, cell, skipMiddleware),
1131
+ );
1132
+ },
1014
1133
  );
1015
- const setOrDelValues = (values) =>
1016
- objIsEmpty(values) ? delValues() : setValues(values);
1017
- const setValidValues = (values) =>
1018
- mapMatch(
1019
- valuesMap,
1134
+ const setValidValues = (values, forceDel) =>
1135
+ ifTransformed(
1020
1136
  values,
1021
- (_valuesMap, valueId, value) => setValidValue(valueId, value),
1022
- (_valuesMap, valueId) => delValidValue(valueId),
1137
+ () =>
1138
+ forceDel
1139
+ ? values
1140
+ : ifNotUndefined(
1141
+ middleware[5],
1142
+ (willSetValues) =>
1143
+ whileMutating(() => willSetValues(structuredClone(values))),
1144
+ () => values,
1145
+ ),
1146
+ (validValues) =>
1147
+ mapMatch(
1148
+ valuesMap,
1149
+ validValues,
1150
+ (_valuesMap, valueId, value) => setValidValue(valueId, value),
1151
+ (_valuesMap, valueId) => delValidValue(valueId),
1152
+ ),
1153
+ objIsEqual,
1154
+ );
1155
+ const setValidValue = (valueId, value, skipMiddleware) =>
1156
+ ifTransformed(
1157
+ value,
1158
+ () =>
1159
+ ifNotUndefined(
1160
+ skipMiddleware ? void 0 : middleware[6],
1161
+ (willSetValue) => whileMutating(() => willSetValue(valueId, value)),
1162
+ () => value,
1163
+ ),
1164
+ (value2) => {
1165
+ if (!collHas(valuesMap, valueId)) {
1166
+ valueIdsChanged(valueId, 1);
1167
+ }
1168
+ const oldValue = mapGet(valuesMap, valueId);
1169
+ if (value2 !== oldValue) {
1170
+ valueChanged(valueId, oldValue, value2);
1171
+ mapSet(valuesMap, valueId, value2);
1172
+ }
1173
+ },
1023
1174
  );
1024
- const setValidValue = (valueId, value) => {
1025
- if (!collHas(valuesMap, valueId)) {
1026
- valueIdsChanged(valueId, 1);
1027
- }
1028
- const oldValue = mapGet(valuesMap, valueId);
1029
- if (value !== oldValue) {
1030
- valueChanged(valueId, oldValue, value);
1031
- mapSet(valuesMap, valueId, value);
1032
- }
1033
- };
1034
1175
  const getNewRowId = (tableId, reuse) => {
1035
1176
  const [getId] = mapGet(tablePoolFunctions, tableId);
1036
1177
  let rowId;
@@ -1040,14 +1181,34 @@ const createStore = () => {
1040
1181
  return rowId;
1041
1182
  };
1042
1183
  const getOrCreateTable = (tableId) =>
1043
- mapGet(tablesMap, tableId) ?? setValidTable(tableId, {});
1044
- const delValidTable = (tableId) => setValidTable(tableId, {});
1184
+ mapEnsure(tablesMap, tableId, () => {
1185
+ tableIdsChanged(tableId, 1);
1186
+ mapSet(tablePoolFunctions, tableId, getPoolFunctions());
1187
+ mapSet(tableCellIds, tableId, mapNew());
1188
+ return mapNew();
1189
+ });
1190
+ const delValidTable = (tableId) => {
1191
+ if (whileMutating(() => middleware[8]?.(tableId)) ?? true) {
1192
+ return setValidTable(tableId, {}, true);
1193
+ }
1194
+ return mapGet(tablesMap, tableId);
1195
+ };
1045
1196
  const delValidRow = (tableId, tableMap, rowId) => {
1046
- const [, releaseId] = mapGet(tablePoolFunctions, tableId);
1047
- releaseId(rowId);
1048
- setValidRow(tableId, tableMap, rowId, {}, true);
1197
+ if (whileMutating(() => middleware[9]?.(tableId, rowId)) ?? true) {
1198
+ const [, releaseId] = mapGet(tablePoolFunctions, tableId);
1199
+ releaseId(rowId);
1200
+ setValidRow(tableId, tableMap, rowId, {}, true);
1201
+ }
1049
1202
  };
1050
- const delValidCell = (tableId, table, rowId, row, cellId, forceDel) => {
1203
+ const delValidCell = (
1204
+ tableId,
1205
+ table,
1206
+ rowId,
1207
+ row,
1208
+ cellId,
1209
+ forceDel,
1210
+ skipMiddleware,
1211
+ ) => {
1051
1212
  const defaultCell = mapGet(
1052
1213
  mapGet(tablesSchemaRowCache, tableId)?.[0],
1053
1214
  cellId,
@@ -1055,34 +1216,44 @@ const createStore = () => {
1055
1216
  if (!isUndefined(defaultCell) && !forceDel) {
1056
1217
  return setValidCell(tableId, rowId, row, cellId, defaultCell);
1057
1218
  }
1058
- const delCell2 = (cellId2) => {
1059
- cellChanged(tableId, rowId, cellId2, mapGet(row, cellId2));
1060
- cellIdsChanged(tableId, rowId, cellId2, -1);
1061
- mapSet(row, cellId2);
1062
- };
1063
- if (isUndefined(defaultCell)) {
1064
- delCell2(cellId);
1065
- } else {
1066
- mapForEach(row, delCell2);
1067
- }
1068
- if (collIsEmpty(row)) {
1069
- rowIdsChanged(tableId, rowId, -1);
1070
- if (collIsEmpty(mapSet(table, rowId))) {
1071
- tableIdsChanged(tableId, -1);
1072
- mapSet(tablesMap, tableId);
1073
- mapSet(tablePoolFunctions, tableId);
1074
- mapSet(tableCellIds, tableId);
1219
+ if (
1220
+ skipMiddleware ||
1221
+ (whileMutating(() => middleware[10]?.(tableId, rowId, cellId)) ?? true)
1222
+ ) {
1223
+ const delCell2 = (cellId2) => {
1224
+ cellChanged(tableId, rowId, cellId2, mapGet(row, cellId2));
1225
+ cellIdsChanged(tableId, rowId, cellId2, -1);
1226
+ mapSet(row, cellId2);
1227
+ };
1228
+ if (isUndefined(defaultCell)) {
1229
+ delCell2(cellId);
1230
+ } else {
1231
+ mapForEach(row, delCell2);
1232
+ }
1233
+ if (collIsEmpty(row)) {
1234
+ rowIdsChanged(tableId, rowId, -1);
1235
+ if (collIsEmpty(mapSet(table, rowId))) {
1236
+ tableIdsChanged(tableId, -1);
1237
+ mapSet(tablesMap, tableId);
1238
+ mapSet(tablePoolFunctions, tableId);
1239
+ mapSet(tableCellIds, tableId);
1240
+ }
1075
1241
  }
1076
1242
  }
1077
1243
  };
1078
- const delValidValue = (valueId) => {
1244
+ const delValidValue = (valueId, skipMiddleware) => {
1079
1245
  const defaultValue = mapGet(valuesDefaulted, valueId);
1080
1246
  if (!isUndefined(defaultValue)) {
1081
1247
  return setValidValue(valueId, defaultValue);
1082
1248
  }
1083
- valueChanged(valueId, mapGet(valuesMap, valueId));
1084
- valueIdsChanged(valueId, -1);
1085
- mapSet(valuesMap, valueId);
1249
+ if (
1250
+ skipMiddleware ||
1251
+ (whileMutating(() => middleware[12]?.(valueId)) ?? true)
1252
+ ) {
1253
+ valueChanged(valueId, mapGet(valuesMap, valueId));
1254
+ valueIdsChanged(valueId, -1);
1255
+ mapSet(valuesMap, valueId);
1256
+ }
1086
1257
  };
1087
1258
  const tableIdsChanged = (tableId, addedOrRemoved) =>
1088
1259
  idsChanged(changedTableIds, tableId, addedOrRemoved);
@@ -1127,13 +1298,13 @@ const createStore = () => {
1127
1298
  cellId,
1128
1299
  () => [oldCell, 0],
1129
1300
  )[1] = newCell;
1130
- internalListeners[3]?.(tableId, rowId, cellId, newCell);
1301
+ internalListeners[3]?.(tableId, rowId, cellId, newCell, mutating);
1131
1302
  };
1132
1303
  const valueIdsChanged = (valueId, addedOrRemoved) =>
1133
1304
  idsChanged(changedValueIds, valueId, addedOrRemoved);
1134
1305
  const valueChanged = (valueId, oldValue, newValue) => {
1135
1306
  mapEnsure(changedValues, valueId, () => [oldValue, 0])[1] = newValue;
1136
- internalListeners[4]?.(valueId, newValue);
1307
+ internalListeners[4]?.(valueId, newValue, mutating);
1137
1308
  };
1138
1309
  const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
1139
1310
  arrayPush(
@@ -1208,14 +1379,11 @@ const createStore = () => {
1208
1379
  }
1209
1380
  };
1210
1381
  const callTabularListenersForChanges = (mutator) => {
1211
- const hasTablesNow = hasTables();
1212
- if (hasTablesNow != hadTables) {
1213
- callListeners(hasTablesListeners[mutator], void 0, hasTablesNow);
1214
- }
1215
- const emptySortedRowIdListeners = collIsEmpty(
1382
+ const hasHasTablesListeners = !collIsEmpty(hasTablesListeners[mutator]);
1383
+ const hasSortedRowIdListeners = !collIsEmpty(
1216
1384
  sortedRowIdsListeners[mutator],
1217
1385
  );
1218
- const emptyIdAndHasListeners =
1386
+ const hasIdOrHasListeners = !(
1219
1387
  collIsEmpty(cellIdsListeners[mutator]) &&
1220
1388
  collIsEmpty(hasCellListeners[mutator]) &&
1221
1389
  collIsEmpty(rowIdsListeners[mutator]) &&
@@ -1223,15 +1391,17 @@ const createStore = () => {
1223
1391
  collIsEmpty(tableCellIdsListeners[mutator]) &&
1224
1392
  collIsEmpty(hasTableCellListeners[mutator]) &&
1225
1393
  collIsEmpty(rowCountListeners[mutator]) &&
1226
- emptySortedRowIdListeners &&
1394
+ !hasSortedRowIdListeners &&
1227
1395
  collIsEmpty(tableIdsListeners[mutator]) &&
1228
- collIsEmpty(hasTableListeners[mutator]);
1229
- const emptyOtherListeners =
1396
+ collIsEmpty(hasTableListeners[mutator])
1397
+ );
1398
+ const hasOtherListeners = !(
1230
1399
  collIsEmpty(cellListeners[mutator]) &&
1231
1400
  collIsEmpty(rowListeners[mutator]) &&
1232
1401
  collIsEmpty(tableListeners[mutator]) &&
1233
- collIsEmpty(tablesListeners[mutator]);
1234
- if (!emptyIdAndHasListeners || !emptyOtherListeners) {
1402
+ collIsEmpty(tablesListeners[mutator])
1403
+ );
1404
+ if (hasHasTablesListeners || hasIdOrHasListeners || hasOtherListeners) {
1235
1405
  const changes = mutator
1236
1406
  ? [
1237
1407
  mapClone(changedTableIds),
@@ -1239,7 +1409,9 @@ const createStore = () => {
1239
1409
  mapClone(changedRowCount),
1240
1410
  mapClone2(changedRowIds),
1241
1411
  mapClone3(changedCellIds),
1242
- mapClone3(changedCells),
1412
+ mapClone(changedCells, (map) =>
1413
+ mapClone(map, (map2) => mapClone(map2, pairClone)),
1414
+ ),
1243
1415
  ]
1244
1416
  : [
1245
1417
  changedTableIds,
@@ -1249,7 +1421,13 @@ const createStore = () => {
1249
1421
  changedCellIds,
1250
1422
  changedCells,
1251
1423
  ];
1252
- if (!emptyIdAndHasListeners) {
1424
+ if (hasHasTablesListeners) {
1425
+ const hasTablesNow = hasTables();
1426
+ if (hasTablesNow != hadTables) {
1427
+ callListeners(hasTablesListeners[mutator], void 0, hasTablesNow);
1428
+ }
1429
+ }
1430
+ if (hasIdOrHasListeners) {
1253
1431
  callIdsAndHasListenersIfChanged(
1254
1432
  changes[0],
1255
1433
  tableIdsListeners[mutator],
@@ -1281,13 +1459,13 @@ const createStore = () => {
1281
1459
  hasRowListeners[mutator],
1282
1460
  [tableId],
1283
1461
  ) &&
1284
- !emptySortedRowIdListeners
1462
+ hasSortedRowIdListeners
1285
1463
  ) {
1286
1464
  callListeners(sortedRowIdsListeners[mutator], [tableId, null]);
1287
1465
  setAdd(calledSortableTableIds, tableId);
1288
1466
  }
1289
1467
  });
1290
- if (!emptySortedRowIdListeners) {
1468
+ if (hasSortedRowIdListeners) {
1291
1469
  collForEach(changes[5], (rows, tableId) => {
1292
1470
  if (!collHas(calledSortableTableIds, tableId)) {
1293
1471
  const sortableCellIds = setNew();
@@ -1318,7 +1496,7 @@ const createStore = () => {
1318
1496
  ),
1319
1497
  );
1320
1498
  }
1321
- if (!emptyOtherListeners) {
1499
+ if (hasOtherListeners) {
1322
1500
  let tablesChanged;
1323
1501
  collForEach(changes[5], (rows, tableId) => {
1324
1502
  let tableChanged;
@@ -1355,28 +1533,31 @@ const createStore = () => {
1355
1533
  }
1356
1534
  };
1357
1535
  const callValuesListenersForChanges = (mutator) => {
1358
- const hasValuesNow = hasValues();
1359
- if (hasValuesNow != hadValues) {
1360
- callListeners(hasValuesListeners[mutator], void 0, hasValuesNow);
1361
- }
1362
- const emptyIdAndHasListeners =
1363
- collIsEmpty(valueIdsListeners[mutator]) &&
1364
- collIsEmpty(hasValueListeners[mutator]);
1365
- const emptyOtherListeners =
1366
- collIsEmpty(valueListeners[mutator]) &&
1367
- collIsEmpty(valuesListeners[mutator]);
1368
- if (!emptyIdAndHasListeners || !emptyOtherListeners) {
1536
+ const hasHasValuesListeners = !collIsEmpty(hasValuesListeners[mutator]);
1537
+ const hasIdOrHasListeners =
1538
+ !collIsEmpty(valueIdsListeners[mutator]) ||
1539
+ !collIsEmpty(hasValueListeners[mutator]);
1540
+ const hasOtherListeners =
1541
+ !collIsEmpty(valueListeners[mutator]) ||
1542
+ !collIsEmpty(valuesListeners[mutator]);
1543
+ if (hasHasValuesListeners || hasIdOrHasListeners || hasOtherListeners) {
1369
1544
  const changes = mutator
1370
- ? [mapClone(changedValueIds), mapClone(changedValues)]
1545
+ ? [mapClone(changedValueIds), mapClone(changedValues, pairClone)]
1371
1546
  : [changedValueIds, changedValues];
1372
- if (!emptyIdAndHasListeners) {
1547
+ if (hasHasValuesListeners) {
1548
+ const hasValuesNow = hasValues();
1549
+ if (hasValuesNow != hadValues) {
1550
+ callListeners(hasValuesListeners[mutator], void 0, hasValuesNow);
1551
+ }
1552
+ }
1553
+ if (hasIdOrHasListeners) {
1373
1554
  callIdsAndHasListenersIfChanged(
1374
1555
  changes[0],
1375
1556
  valueIdsListeners[mutator],
1376
1557
  hasValueListeners[mutator],
1377
1558
  );
1378
1559
  }
1379
- if (!emptyOtherListeners) {
1560
+ if (hasOtherListeners) {
1380
1561
  let valuesChanged;
1381
1562
  collForEach(changes[1], ([oldValue, newValue], valueId) => {
1382
1563
  if (newValue !== oldValue) {
@@ -1531,14 +1712,14 @@ const createStore = () => {
1531
1712
  if (validateRow(tableId2, rowId2, partialRow, 1)) {
1532
1713
  const table = getOrCreateTable(tableId2);
1533
1714
  objMap(partialRow, (cell, cellId) =>
1534
- setCellIntoDefaultRow(tableId2, table, rowId2, cellId, cell),
1715
+ setCellIntoNewRow(tableId2, table, rowId2, cellId, cell),
1535
1716
  );
1536
1717
  }
1537
1718
  },
1538
1719
  tableId,
1539
1720
  rowId,
1540
1721
  );
1541
- const setCell = (tableId, rowId, cellId, cell) =>
1722
+ const setCell = (tableId, rowId, cellId, cell, skipMiddleware) =>
1542
1723
  fluentTransaction(
1543
1724
  (tableId2, rowId2, cellId2) =>
1544
1725
  ifNotUndefined(
@@ -1549,12 +1730,13 @@ const createStore = () => {
1549
1730
  isFunction(cell) ? cell(getCell(tableId2, rowId2, cellId2)) : cell,
1550
1731
  ),
1551
1732
  (validCell) =>
1552
- setCellIntoDefaultRow(
1733
+ setCellIntoNewRow(
1553
1734
  tableId2,
1554
1735
  getOrCreateTable(tableId2),
1555
1736
  rowId2,
1556
1737
  cellId2,
1557
1738
  validCell,
1739
+ skipMiddleware,
1558
1740
  ),
1559
1741
  ),
1560
1742
  tableId,
@@ -1573,7 +1755,7 @@ const createStore = () => {
1573
1755
  )
1574
1756
  : 0,
1575
1757
  );
1576
- const setValue = (valueId, value) =>
1758
+ const setValue = (valueId, value, skipMiddleware) =>
1577
1759
  fluentTransaction(
1578
1760
  (valueId2) =>
1579
1761
  ifNotUndefined(
@@ -1581,27 +1763,40 @@ const createStore = () => {
1581
1763
  valueId2,
1582
1764
  isFunction(value) ? value(getValue(valueId2)) : value,
1583
1765
  ),
1584
- (validValue) => setValidValue(valueId2, validValue),
1766
+ (validValue) => setValidValue(valueId2, validValue, skipMiddleware),
1585
1767
  ),
1586
1768
  valueId,
1587
1769
  );
1588
1770
  const applyChanges = (changes) =>
1589
- fluentTransaction(() => {
1590
- objMap(changes[0], (table, tableId) =>
1591
- isUndefined(table)
1592
- ? delTable(tableId)
1593
- : objMap(table, (row, rowId) =>
1594
- isUndefined(row)
1595
- ? delRow(tableId, rowId)
1596
- : objMap(row, (cell, cellId) =>
1597
- setOrDelCell(store, tableId, rowId, cellId, cell),
1598
- ),
1599
- ),
1600
- );
1601
- objMap(changes[1], (value, valueId) =>
1602
- setOrDelValue(store, valueId, value),
1603
- );
1604
- });
1771
+ fluentTransaction(() =>
1772
+ ifTransformed(
1773
+ changes,
1774
+ () =>
1775
+ ifNotUndefined(
1776
+ middleware[13],
1777
+ (willApplyChanges) =>
1778
+ whileMutating(() => willApplyChanges(structuredClone(changes))),
1779
+ () => changes,
1780
+ ),
1781
+ (changes2) => {
1782
+ objMap(changes2[0], (table, tableId) =>
1783
+ isUndefined(table)
1784
+ ? delTable(tableId)
1785
+ : objMap(table, (row, rowId) =>
1786
+ isUndefined(row)
1787
+ ? delRow(tableId, rowId)
1788
+ : objMap(row, (cell, cellId) =>
1789
+ setOrDelCell(tableId, rowId, cellId, cell),
1790
+ ),
1791
+ ),
1792
+ );
1793
+ objMap(changes2[1], (value, valueId) =>
1794
+ setOrDelValue(valueId, value),
1795
+ );
1796
+ },
1797
+ contentOrChangesIsEqual,
1798
+ ),
1799
+ );
1605
1800
  const setTablesJson = (tablesJson) => {
1606
1801
  tryCatch(() => setOrDelTables(jsonParse(tablesJson)));
1607
1802
  return store;
@@ -1648,7 +1843,12 @@ const createStore = () => {
1648
1843
  setTablesSchema(tablesSchema);
1649
1844
  setValuesSchema(valuesSchema);
1650
1845
  });
1651
- const delTables = () => fluentTransaction(() => setValidTables({}));
1846
+ const delTables = () =>
1847
+ fluentTransaction(() =>
1848
+ (whileMutating(() => middleware[7]?.()) ?? true)
1849
+ ? setValidTables({}, true)
1850
+ : 0,
1851
+ );
1652
1852
  const delTable = (tableId) =>
1653
1853
  fluentTransaction(
1654
1854
  (tableId2) =>
@@ -1666,7 +1866,7 @@ const createStore = () => {
1666
1866
  tableId,
1667
1867
  rowId,
1668
1868
  );
1669
- const delCell = (tableId, rowId, cellId, forceDel) =>
1869
+ const delCell = (tableId, rowId, cellId, forceDel, skipMiddleware) =>
1670
1870
  fluentTransaction(
1671
1871
  (tableId2, rowId2, cellId2) =>
1672
1872
  ifNotUndefined(mapGet(tablesMap, tableId2), (tableMap) =>
@@ -1679,6 +1879,7 @@ const createStore = () => {
1679
1879
  rowMap,
1680
1880
  cellId2,
1681
1881
  forceDel,
1882
+ skipMiddleware,
1682
1883
  )
1683
1884
  : 0,
1684
1885
  ),
@@ -1687,11 +1888,18 @@ const createStore = () => {
1687
1888
  rowId,
1688
1889
  cellId,
1689
1890
  );
1690
- const delValues = () => fluentTransaction(() => setValidValues({}));
1691
- const delValue = (valueId) =>
1891
+ const delValues = () =>
1892
+ fluentTransaction(() =>
1893
+ (whileMutating(() => middleware[11]?.()) ?? true)
1894
+ ? setValidValues({}, true)
1895
+ : 0,
1896
+ );
1897
+ const delValue = (valueId, skipMiddleware) =>
1692
1898
  fluentTransaction(
1693
1899
  (valueId2) =>
1694
- collHas(valuesMap, valueId2) ? delValidValue(valueId2) : 0,
1900
+ collHas(valuesMap, valueId2)
1901
+ ? delValidValue(valueId2, skipMiddleware)
1902
+ : 0,
1695
1903
  valueId,
1696
1904
  );
1697
1905
  const delTablesSchema = () =>
@@ -1773,25 +1981,27 @@ const createStore = () => {
1773
1981
  transactions--;
1774
1982
  if (transactions == 0) {
1775
1983
  transactions = 1;
1776
- callInvalidCellListeners(1);
1777
- if (!collIsEmpty(changedCells)) {
1778
- callTabularListenersForChanges(1);
1779
- }
1780
- callInvalidValueListeners(1);
1781
- if (!collIsEmpty(changedValues)) {
1782
- callValuesListenersForChanges(1);
1783
- }
1984
+ whileMutating(() => {
1985
+ callInvalidCellListeners(1);
1986
+ if (!collIsEmpty(changedCells)) {
1987
+ callTabularListenersForChanges(1);
1988
+ }
1989
+ callInvalidValueListeners(1);
1990
+ if (!collIsEmpty(changedValues)) {
1991
+ callValuesListenersForChanges(1);
1992
+ }
1993
+ });
1784
1994
  if (doRollback?.(store)) {
1785
1995
  collForEach(changedCells, (table, tableId) =>
1786
1996
  collForEach(table, (row, rowId) =>
1787
1997
  collForEach(row, ([oldCell], cellId) =>
1788
- setOrDelCell(store, tableId, rowId, cellId, oldCell),
1998
+ setOrDelCell(tableId, rowId, cellId, oldCell, true),
1789
1999
  ),
1790
2000
  ),
1791
2001
  );
1792
2002
  collClear(changedCells);
1793
2003
  collForEach(changedValues, ([oldValue], valueId) =>
1794
- setOrDelValue(store, valueId, oldValue),
2004
+ setOrDelValue(valueId, oldValue, true),
1795
2005
  );
1796
2006
  collClear(changedValues);
1797
2007
  }
@@ -1918,6 +2128,38 @@ const createStore = () => {
1918
2128
  collSize2(startTransactionListeners) +
1919
2129
  pairCollSize2(finishTransactionListeners),
1920
2130
  });
2131
+ const setMiddleware = (
2132
+ willSetContent,
2133
+ willSetTables,
2134
+ willSetTable,
2135
+ willSetRow,
2136
+ willSetCell,
2137
+ willSetValues,
2138
+ willSetValue,
2139
+ willDelTables,
2140
+ willDelTable,
2141
+ willDelRow,
2142
+ willDelCell,
2143
+ willDelValues,
2144
+ willDelValue,
2145
+ willApplyChanges,
2146
+ ) =>
2147
+ (middleware = [
2148
+ willSetContent,
2149
+ willSetTables,
2150
+ willSetTable,
2151
+ willSetRow,
2152
+ willSetCell,
2153
+ willSetValues,
2154
+ willSetValue,
2155
+ willDelTables,
2156
+ willDelTable,
2157
+ willDelRow,
2158
+ willDelCell,
2159
+ willDelValues,
2160
+ willDelValue,
2161
+ willApplyChanges,
2162
+ ]);
1921
2163
  const setInternalListeners = (
1922
2164
  preStartTransaction,
1923
2165
  preFinishTransaction,
@@ -2011,6 +2253,9 @@ const createStore = () => {
2011
2253
  addListener,
2012
2254
  callListeners,
2013
2255
  setInternalListeners,
2256
+ setMiddleware,
2257
+ setOrDelCell,
2258
+ setOrDelValue,
2014
2259
  };
2015
2260
  objMap(
2016
2261
  {