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
@@ -114,6 +114,7 @@ const noop = () => {};
114
114
  const getArg = (value) => value;
115
115
  const promiseNew = (resolver) => new promise(resolver);
116
116
  const promiseAll = async (promises) => promise.all(promises);
117
+ const structuredClone = GLOBAL.structuredClone;
117
118
  const errorNew = (message) => {
118
119
  throw new Error(message);
119
120
  };
@@ -157,33 +158,6 @@ const arrayUnshift = (array, ...values) => array.unshift(...values);
157
158
  const arrayShift = (array) => array.shift();
158
159
  const arrayWith = (array, index, value) => array.with(index, value);
159
160
 
160
- const getCellOrValueType = (cellOrValue) => {
161
- if (isNull(cellOrValue)) {
162
- return NULL;
163
- }
164
- const type = getTypeOf(cellOrValue);
165
- return isTypeStringOrBoolean(type) ||
166
- (type == NUMBER && isFiniteNumber(cellOrValue))
167
- ? type
168
- : void 0;
169
- };
170
- const isCellOrValueOrUndefined = (cellOrValue) =>
171
- isUndefined(cellOrValue) || !isUndefined(getCellOrValueType(cellOrValue));
172
- const setOrDelCell = (store, tableId, rowId, cellId, cell) =>
173
- isUndefined(cell)
174
- ? store.delCell(tableId, rowId, cellId, true)
175
- : store.setCell(tableId, rowId, cellId, cell);
176
- const setOrDelValue = (store, valueId, value) =>
177
- isUndefined(value) ? store.delValue(valueId) : store.setValue(valueId, value);
178
- const getTypeCase = (type, stringCase, numberCase, booleanCase) =>
179
- type == STRING
180
- ? stringCase
181
- : type == NUMBER
182
- ? numberCase
183
- : type == BOOLEAN
184
- ? booleanCase
185
- : null;
186
-
187
161
  const collSizeN = (collSizer) => (coll) =>
188
162
  arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
189
163
  const collSize = (coll) => coll?.size ?? 0;
@@ -276,31 +250,32 @@ const objValidate = (obj, validateChild, onInvalidObj, emptyIsValid = 0) => {
276
250
  return emptyIsValid ? true : !objIsEmpty(obj);
277
251
  };
278
252
 
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));
253
+ const map = Map;
254
+ const mapNew = (entries) => new map(entries);
255
+ const mapKeys = (map2) => [...(map2?.keys() ?? [])];
256
+ const mapGet = (map2, key) => map2?.get(key);
257
+ const mapForEach = (map2, cb) =>
258
+ collForEach(map2, (value, key) => cb(key, value));
284
259
  const mapMap = (coll, cb) =>
285
260
  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());
261
+ const mapSet = (map2, key, value) =>
262
+ isUndefined(value) ? (collDel(map2, key), map2) : map2?.set(key, value);
263
+ const mapEnsure = (map2, key, getDefaultValue, hadExistingValue) => {
264
+ if (!collHas(map2, key)) {
265
+ mapSet(map2, key, getDefaultValue());
291
266
  } else {
292
- hadExistingValue?.(mapGet(map, key));
267
+ hadExistingValue?.(mapGet(map2, key));
293
268
  }
294
- return mapGet(map, key);
269
+ return mapGet(map2, key);
295
270
  };
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;
271
+ const mapMatch = (map2, obj, set, del = mapSet) => {
272
+ objMap(obj, (value, id) => set(map2, id, value));
273
+ mapForEach(map2, (id) => (objHas(obj, id) ? 0 : del(map2, id)));
274
+ return map2;
300
275
  };
301
- const mapToObj = (map, valueMapper, excludeMapValue, excludeObjValue) => {
276
+ const mapToObj = (map2, valueMapper, excludeMapValue, excludeObjValue) => {
302
277
  const obj = {};
303
- collForEach(map, (mapValue, id) => {
278
+ collForEach(map2, (mapValue, id) => {
304
279
  if (!excludeMapValue?.(mapValue, id)) {
305
280
  const objValue = valueMapper ? valueMapper(mapValue, id) : mapValue;
306
281
  if (!excludeObjValue?.(objValue)) {
@@ -310,27 +285,27 @@ const mapToObj = (map, valueMapper, excludeMapValue, excludeObjValue) => {
310
285
  });
311
286
  return obj;
312
287
  };
313
- const mapToObj2 = (map, valueMapper, excludeMapValue) =>
288
+ const mapToObj2 = (map2, valueMapper, excludeMapValue) =>
314
289
  mapToObj(
315
- map,
290
+ map2,
316
291
  (childMap) => mapToObj(childMap, valueMapper, excludeMapValue),
317
292
  collIsEmpty,
318
293
  objIsEmpty,
319
294
  );
320
- const mapToObj3 = (map, valueMapper, excludeMapValue) =>
295
+ const mapToObj3 = (map2, valueMapper, excludeMapValue) =>
321
296
  mapToObj(
322
- map,
297
+ map2,
323
298
  (childMap) => mapToObj2(childMap, valueMapper, excludeMapValue),
324
299
  collIsEmpty,
325
300
  objIsEmpty,
326
301
  );
327
- const mapClone = (map, mapValue) => {
328
- const map2 = mapNew();
329
- collForEach(map, (value, key) => map2.set(key, mapValue?.(value) ?? value));
330
- return map2;
302
+ const mapClone = (map2, mapValue) => {
303
+ const map22 = mapNew();
304
+ collForEach(map2, (value, key) => map22.set(key, mapValue?.(value) ?? value));
305
+ return map22;
331
306
  };
332
- const mapClone2 = (map) => mapClone(map, mapClone);
333
- const mapClone3 = (map) => mapClone(map, mapClone2);
307
+ const mapClone2 = (map2) => mapClone(map2, mapClone);
308
+ const mapClone3 = (map2) => mapClone(map2, mapClone2);
334
309
  const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
335
310
  ifNotUndefined(
336
311
  (ensureLeaf ? mapEnsure : mapGet)(
@@ -644,12 +619,18 @@ const createCheckpoints = getCreateFunction(
644
619
  collForEach(cellsDelta2, (table, tableId) =>
645
620
  collForEach(table, (row, rowId) =>
646
621
  collForEach(row, (oldNew, cellId) =>
647
- setOrDelCell(store, tableId, rowId, cellId, oldNew[oldOrNew]),
622
+ store.setOrDelCell(
623
+ tableId,
624
+ rowId,
625
+ cellId,
626
+ oldNew[oldOrNew],
627
+ true,
628
+ ),
648
629
  ),
649
630
  ),
650
631
  );
651
632
  collForEach(valuesDelta2, (oldNew, valueId) =>
652
- setOrDelValue(store, valueId, oldNew[oldOrNew]),
633
+ store.setOrDelValue(valueId, oldNew[oldOrNew], true),
653
634
  );
654
635
  });
655
636
  listening = 1;
@@ -899,7 +880,16 @@ const jsonStringWithMap = (obj) =>
899
880
  const jsonStringWithUndefined = (obj) =>
900
881
  jsonString(obj, (_key, value) => (isUndefined(value) ? UNDEFINED : value));
901
882
  const jsonParseWithUndefined = (str) =>
902
- jsonParse(str, (_key, value) => (value === UNDEFINED ? void 0 : value));
883
+ // JSON.parse reviver removes properties with undefined values
884
+ replaceUndefinedString(jsonParse(str));
885
+ const replaceUndefinedString = (obj) =>
886
+ obj === UNDEFINED
887
+ ? void 0
888
+ : isArray(obj)
889
+ ? arrayMap(obj, replaceUndefinedString)
890
+ : isObject(obj)
891
+ ? objMap(obj, replaceUndefinedString)
892
+ : obj;
903
893
 
904
894
  const textEncoder = /* @__PURE__ */ new GLOBAL.TextEncoder();
905
895
  const getHash = (string) => {
@@ -1239,6 +1229,27 @@ const createIndexes = getCreateFunction((store) => {
1239
1229
  return objFreeze(indexes);
1240
1230
  });
1241
1231
 
1232
+ const getCellOrValueType = (cellOrValue) => {
1233
+ if (isNull(cellOrValue)) {
1234
+ return NULL;
1235
+ }
1236
+ const type = getTypeOf(cellOrValue);
1237
+ return isTypeStringOrBoolean(type) ||
1238
+ (type == NUMBER && isFiniteNumber(cellOrValue))
1239
+ ? type
1240
+ : void 0;
1241
+ };
1242
+ const isCellOrValueOrUndefined = (cellOrValue) =>
1243
+ isUndefined(cellOrValue) || !isUndefined(getCellOrValueType(cellOrValue));
1244
+ const getTypeCase = (type, stringCase, numberCase, booleanCase) =>
1245
+ type == STRING
1246
+ ? stringCase
1247
+ : type == NUMBER
1248
+ ? numberCase
1249
+ : type == BOOLEAN
1250
+ ? booleanCase
1251
+ : null;
1252
+
1242
1253
  const stampClone = ([value, hlc]) => stampNew(value, hlc);
1243
1254
  const stampCloneWithHash = ([value, hlc, hash]) => [value, hlc, hash];
1244
1255
  const stampNew = (value, hlc) => (hlc ? [value, hlc] : [value]);
@@ -1283,13 +1294,17 @@ const idsChanged = (changedIds, id2, addedOrRemoved) =>
1283
1294
  id2,
1284
1295
  mapGet(changedIds, id2) == -addedOrRemoved ? void 0 : addedOrRemoved,
1285
1296
  );
1297
+ const contentOrChangesIsEqual = ([tables1, values1], [tables2, values2]) =>
1298
+ objIsEqual(tables1, tables2) && objIsEqual(values1, values2);
1286
1299
  const createStore = () => {
1287
1300
  let hasTablesSchema;
1288
1301
  let hasValuesSchema;
1289
1302
  let hadTables = false;
1290
1303
  let hadValues = false;
1291
1304
  let transactions = 0;
1305
+ let middleware = [];
1292
1306
  let internalListeners = [];
1307
+ let mutating = 0;
1293
1308
  const changedTableIds = mapNew();
1294
1309
  const changedTableCellIds = mapNew();
1295
1310
  const changedRowCount = mapNew();
@@ -1335,6 +1350,19 @@ const createStore = () => {
1335
1350
  const finishTransactionListeners = pairNewMap();
1336
1351
  const [addListener, callListeners, delListenerImpl, callListenerImpl] =
1337
1352
  getListenerFunctions(() => store);
1353
+ const whileMutating = (action) => {
1354
+ const wasMutating = mutating;
1355
+ mutating = 1;
1356
+ const result = action();
1357
+ mutating = wasMutating;
1358
+ return result;
1359
+ };
1360
+ const ifTransformed = (snapshot, getResult, then, isEqual = Object.is) =>
1361
+ ifNotUndefined(getResult(), (result) =>
1362
+ snapshot === result || isEqual(snapshot, result)
1363
+ ? then(result)
1364
+ : whileMutating(() => then(result)),
1365
+ );
1338
1366
  const validateTablesSchema = (tableSchema) =>
1339
1367
  objValidate(tableSchema, (tableSchema2) =>
1340
1368
  objValidate(tableSchema2, validateCellOrValueSchema),
@@ -1522,82 +1550,194 @@ const createStore = () => {
1522
1550
  );
1523
1551
  const setOrDelTables = (tables) =>
1524
1552
  objIsEmpty(tables) ? delTables() : setTables(tables);
1525
- const setValidContent = ([tables, values]) => {
1526
- (objIsEmpty(tables) ? delTables : setTables)(tables);
1527
- (objIsEmpty(values) ? delValues : setValues)(values);
1528
- };
1529
- const setValidTables = (tables) =>
1530
- mapMatch(
1531
- tablesMap,
1553
+ const setOrDelCell = (tableId, rowId, cellId, cell, skipMiddleware) =>
1554
+ isUndefined(cell)
1555
+ ? delCell(tableId, rowId, cellId, true, skipMiddleware)
1556
+ : setCell(tableId, rowId, cellId, cell, skipMiddleware);
1557
+ const setOrDelValues = (values) =>
1558
+ objIsEmpty(values) ? delValues() : setValues(values);
1559
+ const setOrDelValue = (valueId, value, skipMiddleware) =>
1560
+ isUndefined(value)
1561
+ ? delValue(valueId, skipMiddleware)
1562
+ : setValue(valueId, value, skipMiddleware);
1563
+ const setValidContent = (content) =>
1564
+ ifTransformed(
1565
+ content,
1566
+ () =>
1567
+ ifNotUndefined(
1568
+ middleware[0],
1569
+ (willSetContent) =>
1570
+ whileMutating(() => willSetContent(structuredClone(content))),
1571
+ () => content,
1572
+ ),
1573
+ ([tables, values]) => {
1574
+ (objIsEmpty(tables) ? delTables : setTables)(tables);
1575
+ (objIsEmpty(values) ? delValues : setValues)(values);
1576
+ },
1577
+ contentOrChangesIsEqual,
1578
+ );
1579
+ const setValidTables = (tables, forceDel) =>
1580
+ ifTransformed(
1532
1581
  tables,
1533
- (_tables, tableId, table) => setValidTable(tableId, table),
1534
- (_tables, tableId) => delValidTable(tableId),
1582
+ () =>
1583
+ forceDel
1584
+ ? tables
1585
+ : ifNotUndefined(
1586
+ middleware[1],
1587
+ (willSetTables) =>
1588
+ whileMutating(() => willSetTables(structuredClone(tables))),
1589
+ () => tables,
1590
+ ),
1591
+ (validTables) =>
1592
+ mapMatch(
1593
+ tablesMap,
1594
+ validTables,
1595
+ (_tables, tableId, table) => setValidTable(tableId, table),
1596
+ (_tables, tableId) => delValidTable(tableId),
1597
+ ),
1598
+ objIsEqual,
1535
1599
  );
1536
- const setValidTable = (tableId, table) =>
1537
- mapMatch(
1538
- mapEnsure(tablesMap, tableId, () => {
1539
- tableIdsChanged(tableId, 1);
1540
- mapSet(tablePoolFunctions, tableId, getPoolFunctions());
1541
- mapSet(tableCellIds, tableId, mapNew());
1542
- return mapNew();
1543
- }),
1600
+ const setValidTable = (tableId, table, forceDel) =>
1601
+ ifTransformed(
1544
1602
  table,
1545
- (tableMap, rowId, row) => setValidRow(tableId, tableMap, rowId, row),
1546
- (tableMap, rowId) => delValidRow(tableId, tableMap, rowId),
1603
+ () =>
1604
+ forceDel
1605
+ ? table
1606
+ : ifNotUndefined(
1607
+ middleware[2],
1608
+ (willSetTable) =>
1609
+ whileMutating(() =>
1610
+ willSetTable(tableId, structuredClone(table)),
1611
+ ),
1612
+ () => table,
1613
+ ),
1614
+ (validTable) =>
1615
+ mapMatch(
1616
+ mapEnsure(tablesMap, tableId, () => {
1617
+ tableIdsChanged(tableId, 1);
1618
+ mapSet(tablePoolFunctions, tableId, getPoolFunctions());
1619
+ mapSet(tableCellIds, tableId, mapNew());
1620
+ return mapNew();
1621
+ }),
1622
+ validTable,
1623
+ (tableMap, rowId, row) => setValidRow(tableId, tableMap, rowId, row),
1624
+ (tableMap, rowId) => delValidRow(tableId, tableMap, rowId),
1625
+ ),
1626
+ objIsEqual,
1547
1627
  );
1548
1628
  const setValidRow = (tableId, tableMap, rowId, row, forceDel) =>
1549
- mapMatch(
1550
- mapEnsure(tableMap, rowId, () => {
1551
- rowIdsChanged(tableId, rowId, 1);
1552
- return mapNew();
1553
- }),
1629
+ ifTransformed(
1554
1630
  row,
1555
- (rowMap, cellId, cell) =>
1556
- setValidCell(tableId, rowId, rowMap, cellId, cell),
1557
- (rowMap, cellId) =>
1558
- delValidCell(tableId, tableMap, rowId, rowMap, cellId, forceDel),
1559
- );
1560
- const setValidCell = (tableId, rowId, rowMap, cellId, cell) => {
1561
- if (!collHas(rowMap, cellId)) {
1562
- cellIdsChanged(tableId, rowId, cellId, 1);
1563
- }
1564
- const oldCell = mapGet(rowMap, cellId);
1565
- if (cell !== oldCell) {
1566
- cellChanged(tableId, rowId, cellId, oldCell, cell);
1567
- mapSet(rowMap, cellId, cell);
1568
- }
1569
- };
1570
- const setCellIntoDefaultRow = (tableId, tableMap, rowId, cellId, validCell) =>
1631
+ () =>
1632
+ forceDel
1633
+ ? row
1634
+ : ifNotUndefined(
1635
+ middleware[3],
1636
+ (willSetRow) =>
1637
+ whileMutating(() =>
1638
+ willSetRow(tableId, rowId, structuredClone(row)),
1639
+ ),
1640
+ () => row,
1641
+ ),
1642
+ (validRow) =>
1643
+ mapMatch(
1644
+ mapEnsure(tableMap, rowId, () => {
1645
+ rowIdsChanged(tableId, rowId, 1);
1646
+ return mapNew();
1647
+ }),
1648
+ validRow,
1649
+ (rowMap, cellId, cell) =>
1650
+ setValidCell(tableId, rowId, rowMap, cellId, cell),
1651
+ (rowMap, cellId) =>
1652
+ delValidCell(tableId, tableMap, rowId, rowMap, cellId, forceDel),
1653
+ ),
1654
+ objIsEqual,
1655
+ );
1656
+ const setValidCell = (tableId, rowId, rowMap, cellId, cell, skipMiddleware) =>
1657
+ ifTransformed(
1658
+ cell,
1659
+ () =>
1660
+ ifNotUndefined(
1661
+ skipMiddleware ? void 0 : middleware[4],
1662
+ (willSetCell) =>
1663
+ whileMutating(() => willSetCell(tableId, rowId, cellId, cell)),
1664
+ () => cell,
1665
+ ),
1666
+ (cell2) => {
1667
+ if (!collHas(rowMap, cellId)) {
1668
+ cellIdsChanged(tableId, rowId, cellId, 1);
1669
+ }
1670
+ const oldCell = mapGet(rowMap, cellId);
1671
+ if (cell2 !== oldCell) {
1672
+ cellChanged(tableId, rowId, cellId, oldCell, cell2);
1673
+ mapSet(rowMap, cellId, cell2);
1674
+ }
1675
+ },
1676
+ );
1677
+ const setCellIntoNewRow = (
1678
+ tableId,
1679
+ tableMap,
1680
+ rowId,
1681
+ cellId,
1682
+ validCell,
1683
+ skipMiddleware,
1684
+ ) =>
1571
1685
  ifNotUndefined(
1572
1686
  mapGet(tableMap, rowId),
1573
- (rowMap) => setValidCell(tableId, rowId, rowMap, cellId, validCell),
1574
- () =>
1575
- setValidRow(
1576
- tableId,
1577
- tableMap,
1578
- rowId,
1687
+ (rowMap) =>
1688
+ setValidCell(tableId, rowId, rowMap, cellId, validCell, skipMiddleware),
1689
+ () => {
1690
+ const rowMap = mapNew();
1691
+ mapSet(tableMap, rowId, rowMap);
1692
+ rowIdsChanged(tableId, rowId, 1);
1693
+ objMap(
1579
1694
  addDefaultsToRow({[cellId]: validCell}, tableId, rowId),
1580
- ),
1695
+ (cell, cellId2) =>
1696
+ setValidCell(tableId, rowId, rowMap, cellId2, cell, skipMiddleware),
1697
+ );
1698
+ },
1581
1699
  );
1582
- const setOrDelValues = (values) =>
1583
- objIsEmpty(values) ? delValues() : setValues(values);
1584
- const setValidValues = (values) =>
1585
- mapMatch(
1586
- valuesMap,
1700
+ const setValidValues = (values, forceDel) =>
1701
+ ifTransformed(
1587
1702
  values,
1588
- (_valuesMap, valueId, value) => setValidValue(valueId, value),
1589
- (_valuesMap, valueId) => delValidValue(valueId),
1703
+ () =>
1704
+ forceDel
1705
+ ? values
1706
+ : ifNotUndefined(
1707
+ middleware[5],
1708
+ (willSetValues) =>
1709
+ whileMutating(() => willSetValues(structuredClone(values))),
1710
+ () => values,
1711
+ ),
1712
+ (validValues) =>
1713
+ mapMatch(
1714
+ valuesMap,
1715
+ validValues,
1716
+ (_valuesMap, valueId, value) => setValidValue(valueId, value),
1717
+ (_valuesMap, valueId) => delValidValue(valueId),
1718
+ ),
1719
+ objIsEqual,
1720
+ );
1721
+ const setValidValue = (valueId, value, skipMiddleware) =>
1722
+ ifTransformed(
1723
+ value,
1724
+ () =>
1725
+ ifNotUndefined(
1726
+ skipMiddleware ? void 0 : middleware[6],
1727
+ (willSetValue) => whileMutating(() => willSetValue(valueId, value)),
1728
+ () => value,
1729
+ ),
1730
+ (value2) => {
1731
+ if (!collHas(valuesMap, valueId)) {
1732
+ valueIdsChanged(valueId, 1);
1733
+ }
1734
+ const oldValue = mapGet(valuesMap, valueId);
1735
+ if (value2 !== oldValue) {
1736
+ valueChanged(valueId, oldValue, value2);
1737
+ mapSet(valuesMap, valueId, value2);
1738
+ }
1739
+ },
1590
1740
  );
1591
- const setValidValue = (valueId, value) => {
1592
- if (!collHas(valuesMap, valueId)) {
1593
- valueIdsChanged(valueId, 1);
1594
- }
1595
- const oldValue = mapGet(valuesMap, valueId);
1596
- if (value !== oldValue) {
1597
- valueChanged(valueId, oldValue, value);
1598
- mapSet(valuesMap, valueId, value);
1599
- }
1600
- };
1601
1741
  const getNewRowId = (tableId, reuse) => {
1602
1742
  const [getId] = mapGet(tablePoolFunctions, tableId);
1603
1743
  let rowId;
@@ -1607,14 +1747,34 @@ const createStore = () => {
1607
1747
  return rowId;
1608
1748
  };
1609
1749
  const getOrCreateTable = (tableId) =>
1610
- mapGet(tablesMap, tableId) ?? setValidTable(tableId, {});
1611
- const delValidTable = (tableId) => setValidTable(tableId, {});
1750
+ mapEnsure(tablesMap, tableId, () => {
1751
+ tableIdsChanged(tableId, 1);
1752
+ mapSet(tablePoolFunctions, tableId, getPoolFunctions());
1753
+ mapSet(tableCellIds, tableId, mapNew());
1754
+ return mapNew();
1755
+ });
1756
+ const delValidTable = (tableId) => {
1757
+ if (whileMutating(() => middleware[8]?.(tableId)) ?? true) {
1758
+ return setValidTable(tableId, {}, true);
1759
+ }
1760
+ return mapGet(tablesMap, tableId);
1761
+ };
1612
1762
  const delValidRow = (tableId, tableMap, rowId) => {
1613
- const [, releaseId] = mapGet(tablePoolFunctions, tableId);
1614
- releaseId(rowId);
1615
- setValidRow(tableId, tableMap, rowId, {}, true);
1763
+ if (whileMutating(() => middleware[9]?.(tableId, rowId)) ?? true) {
1764
+ const [, releaseId] = mapGet(tablePoolFunctions, tableId);
1765
+ releaseId(rowId);
1766
+ setValidRow(tableId, tableMap, rowId, {}, true);
1767
+ }
1616
1768
  };
1617
- const delValidCell = (tableId, table, rowId, row, cellId, forceDel) => {
1769
+ const delValidCell = (
1770
+ tableId,
1771
+ table,
1772
+ rowId,
1773
+ row,
1774
+ cellId,
1775
+ forceDel,
1776
+ skipMiddleware,
1777
+ ) => {
1618
1778
  const defaultCell = mapGet(
1619
1779
  mapGet(tablesSchemaRowCache, tableId)?.[0],
1620
1780
  cellId,
@@ -1622,34 +1782,44 @@ const createStore = () => {
1622
1782
  if (!isUndefined(defaultCell) && !forceDel) {
1623
1783
  return setValidCell(tableId, rowId, row, cellId, defaultCell);
1624
1784
  }
1625
- const delCell2 = (cellId2) => {
1626
- cellChanged(tableId, rowId, cellId2, mapGet(row, cellId2));
1627
- cellIdsChanged(tableId, rowId, cellId2, -1);
1628
- mapSet(row, cellId2);
1629
- };
1630
- if (isUndefined(defaultCell)) {
1631
- delCell2(cellId);
1632
- } else {
1633
- mapForEach(row, delCell2);
1634
- }
1635
- if (collIsEmpty(row)) {
1636
- rowIdsChanged(tableId, rowId, -1);
1637
- if (collIsEmpty(mapSet(table, rowId))) {
1638
- tableIdsChanged(tableId, -1);
1639
- mapSet(tablesMap, tableId);
1640
- mapSet(tablePoolFunctions, tableId);
1641
- mapSet(tableCellIds, tableId);
1785
+ if (
1786
+ skipMiddleware ||
1787
+ (whileMutating(() => middleware[10]?.(tableId, rowId, cellId)) ?? true)
1788
+ ) {
1789
+ const delCell2 = (cellId2) => {
1790
+ cellChanged(tableId, rowId, cellId2, mapGet(row, cellId2));
1791
+ cellIdsChanged(tableId, rowId, cellId2, -1);
1792
+ mapSet(row, cellId2);
1793
+ };
1794
+ if (isUndefined(defaultCell)) {
1795
+ delCell2(cellId);
1796
+ } else {
1797
+ mapForEach(row, delCell2);
1798
+ }
1799
+ if (collIsEmpty(row)) {
1800
+ rowIdsChanged(tableId, rowId, -1);
1801
+ if (collIsEmpty(mapSet(table, rowId))) {
1802
+ tableIdsChanged(tableId, -1);
1803
+ mapSet(tablesMap, tableId);
1804
+ mapSet(tablePoolFunctions, tableId);
1805
+ mapSet(tableCellIds, tableId);
1806
+ }
1642
1807
  }
1643
1808
  }
1644
1809
  };
1645
- const delValidValue = (valueId) => {
1810
+ const delValidValue = (valueId, skipMiddleware) => {
1646
1811
  const defaultValue = mapGet(valuesDefaulted, valueId);
1647
1812
  if (!isUndefined(defaultValue)) {
1648
1813
  return setValidValue(valueId, defaultValue);
1649
1814
  }
1650
- valueChanged(valueId, mapGet(valuesMap, valueId));
1651
- valueIdsChanged(valueId, -1);
1652
- mapSet(valuesMap, valueId);
1815
+ if (
1816
+ skipMiddleware ||
1817
+ (whileMutating(() => middleware[12]?.(valueId)) ?? true)
1818
+ ) {
1819
+ valueChanged(valueId, mapGet(valuesMap, valueId));
1820
+ valueIdsChanged(valueId, -1);
1821
+ mapSet(valuesMap, valueId);
1822
+ }
1653
1823
  };
1654
1824
  const tableIdsChanged = (tableId, addedOrRemoved) =>
1655
1825
  idsChanged(changedTableIds, tableId, addedOrRemoved);
@@ -1694,13 +1864,13 @@ const createStore = () => {
1694
1864
  cellId,
1695
1865
  () => [oldCell, 0],
1696
1866
  )[1] = newCell;
1697
- internalListeners[3]?.(tableId, rowId, cellId, newCell);
1867
+ internalListeners[3]?.(tableId, rowId, cellId, newCell, mutating);
1698
1868
  };
1699
1869
  const valueIdsChanged = (valueId, addedOrRemoved) =>
1700
1870
  idsChanged(changedValueIds, valueId, addedOrRemoved);
1701
1871
  const valueChanged = (valueId, oldValue, newValue) => {
1702
1872
  mapEnsure(changedValues, valueId, () => [oldValue, 0])[1] = newValue;
1703
- internalListeners[4]?.(valueId, newValue);
1873
+ internalListeners[4]?.(valueId, newValue, mutating);
1704
1874
  };
1705
1875
  const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
1706
1876
  arrayPush(
@@ -1775,14 +1945,11 @@ const createStore = () => {
1775
1945
  }
1776
1946
  };
1777
1947
  const callTabularListenersForChanges = (mutator) => {
1778
- const hasTablesNow = hasTables();
1779
- if (hasTablesNow != hadTables) {
1780
- callListeners(hasTablesListeners[mutator], void 0, hasTablesNow);
1781
- }
1782
- const emptySortedRowIdListeners = collIsEmpty(
1948
+ const hasHasTablesListeners = !collIsEmpty(hasTablesListeners[mutator]);
1949
+ const hasSortedRowIdListeners = !collIsEmpty(
1783
1950
  sortedRowIdsListeners[mutator],
1784
1951
  );
1785
- const emptyIdAndHasListeners =
1952
+ const hasIdOrHasListeners = !(
1786
1953
  collIsEmpty(cellIdsListeners[mutator]) &&
1787
1954
  collIsEmpty(hasCellListeners[mutator]) &&
1788
1955
  collIsEmpty(rowIdsListeners[mutator]) &&
@@ -1790,15 +1957,17 @@ const createStore = () => {
1790
1957
  collIsEmpty(tableCellIdsListeners[mutator]) &&
1791
1958
  collIsEmpty(hasTableCellListeners[mutator]) &&
1792
1959
  collIsEmpty(rowCountListeners[mutator]) &&
1793
- emptySortedRowIdListeners &&
1960
+ !hasSortedRowIdListeners &&
1794
1961
  collIsEmpty(tableIdsListeners[mutator]) &&
1795
- collIsEmpty(hasTableListeners[mutator]);
1796
- const emptyOtherListeners =
1962
+ collIsEmpty(hasTableListeners[mutator])
1963
+ );
1964
+ const hasOtherListeners = !(
1797
1965
  collIsEmpty(cellListeners[mutator]) &&
1798
1966
  collIsEmpty(rowListeners[mutator]) &&
1799
1967
  collIsEmpty(tableListeners[mutator]) &&
1800
- collIsEmpty(tablesListeners[mutator]);
1801
- if (!emptyIdAndHasListeners || !emptyOtherListeners) {
1968
+ collIsEmpty(tablesListeners[mutator])
1969
+ );
1970
+ if (hasHasTablesListeners || hasIdOrHasListeners || hasOtherListeners) {
1802
1971
  const changes = mutator
1803
1972
  ? [
1804
1973
  mapClone(changedTableIds),
@@ -1806,7 +1975,9 @@ const createStore = () => {
1806
1975
  mapClone(changedRowCount),
1807
1976
  mapClone2(changedRowIds),
1808
1977
  mapClone3(changedCellIds),
1809
- mapClone3(changedCells),
1978
+ mapClone(changedCells, (map) =>
1979
+ mapClone(map, (map2) => mapClone(map2, pairClone)),
1980
+ ),
1810
1981
  ]
1811
1982
  : [
1812
1983
  changedTableIds,
@@ -1816,7 +1987,13 @@ const createStore = () => {
1816
1987
  changedCellIds,
1817
1988
  changedCells,
1818
1989
  ];
1819
- if (!emptyIdAndHasListeners) {
1990
+ if (hasHasTablesListeners) {
1991
+ const hasTablesNow = hasTables();
1992
+ if (hasTablesNow != hadTables) {
1993
+ callListeners(hasTablesListeners[mutator], void 0, hasTablesNow);
1994
+ }
1995
+ }
1996
+ if (hasIdOrHasListeners) {
1820
1997
  callIdsAndHasListenersIfChanged(
1821
1998
  changes[0],
1822
1999
  tableIdsListeners[mutator],
@@ -1848,13 +2025,13 @@ const createStore = () => {
1848
2025
  hasRowListeners[mutator],
1849
2026
  [tableId],
1850
2027
  ) &&
1851
- !emptySortedRowIdListeners
2028
+ hasSortedRowIdListeners
1852
2029
  ) {
1853
2030
  callListeners(sortedRowIdsListeners[mutator], [tableId, null]);
1854
2031
  setAdd(calledSortableTableIds, tableId);
1855
2032
  }
1856
2033
  });
1857
- if (!emptySortedRowIdListeners) {
2034
+ if (hasSortedRowIdListeners) {
1858
2035
  collForEach(changes[5], (rows, tableId) => {
1859
2036
  if (!collHas(calledSortableTableIds, tableId)) {
1860
2037
  const sortableCellIds = setNew();
@@ -1885,7 +2062,7 @@ const createStore = () => {
1885
2062
  ),
1886
2063
  );
1887
2064
  }
1888
- if (!emptyOtherListeners) {
2065
+ if (hasOtherListeners) {
1889
2066
  let tablesChanged;
1890
2067
  collForEach(changes[5], (rows, tableId) => {
1891
2068
  let tableChanged;
@@ -1922,28 +2099,31 @@ const createStore = () => {
1922
2099
  }
1923
2100
  };
1924
2101
  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) {
2102
+ const hasHasValuesListeners = !collIsEmpty(hasValuesListeners[mutator]);
2103
+ const hasIdOrHasListeners =
2104
+ !collIsEmpty(valueIdsListeners[mutator]) ||
2105
+ !collIsEmpty(hasValueListeners[mutator]);
2106
+ const hasOtherListeners =
2107
+ !collIsEmpty(valueListeners[mutator]) ||
2108
+ !collIsEmpty(valuesListeners[mutator]);
2109
+ if (hasHasValuesListeners || hasIdOrHasListeners || hasOtherListeners) {
1936
2110
  const changes = mutator
1937
- ? [mapClone(changedValueIds), mapClone(changedValues)]
2111
+ ? [mapClone(changedValueIds), mapClone(changedValues, pairClone)]
1938
2112
  : [changedValueIds, changedValues];
1939
- if (!emptyIdAndHasListeners) {
2113
+ if (hasHasValuesListeners) {
2114
+ const hasValuesNow = hasValues();
2115
+ if (hasValuesNow != hadValues) {
2116
+ callListeners(hasValuesListeners[mutator], void 0, hasValuesNow);
2117
+ }
2118
+ }
2119
+ if (hasIdOrHasListeners) {
1940
2120
  callIdsAndHasListenersIfChanged(
1941
2121
  changes[0],
1942
2122
  valueIdsListeners[mutator],
1943
2123
  hasValueListeners[mutator],
1944
2124
  );
1945
2125
  }
1946
- if (!emptyOtherListeners) {
2126
+ if (hasOtherListeners) {
1947
2127
  let valuesChanged;
1948
2128
  collForEach(changes[1], ([oldValue, newValue], valueId) => {
1949
2129
  if (newValue !== oldValue) {
@@ -2098,14 +2278,14 @@ const createStore = () => {
2098
2278
  if (validateRow(tableId2, rowId2, partialRow, 1)) {
2099
2279
  const table = getOrCreateTable(tableId2);
2100
2280
  objMap(partialRow, (cell, cellId) =>
2101
- setCellIntoDefaultRow(tableId2, table, rowId2, cellId, cell),
2281
+ setCellIntoNewRow(tableId2, table, rowId2, cellId, cell),
2102
2282
  );
2103
2283
  }
2104
2284
  },
2105
2285
  tableId,
2106
2286
  rowId,
2107
2287
  );
2108
- const setCell = (tableId, rowId, cellId, cell) =>
2288
+ const setCell = (tableId, rowId, cellId, cell, skipMiddleware) =>
2109
2289
  fluentTransaction(
2110
2290
  (tableId2, rowId2, cellId2) =>
2111
2291
  ifNotUndefined(
@@ -2116,12 +2296,13 @@ const createStore = () => {
2116
2296
  isFunction(cell) ? cell(getCell(tableId2, rowId2, cellId2)) : cell,
2117
2297
  ),
2118
2298
  (validCell) =>
2119
- setCellIntoDefaultRow(
2299
+ setCellIntoNewRow(
2120
2300
  tableId2,
2121
2301
  getOrCreateTable(tableId2),
2122
2302
  rowId2,
2123
2303
  cellId2,
2124
2304
  validCell,
2305
+ skipMiddleware,
2125
2306
  ),
2126
2307
  ),
2127
2308
  tableId,
@@ -2140,7 +2321,7 @@ const createStore = () => {
2140
2321
  )
2141
2322
  : 0,
2142
2323
  );
2143
- const setValue = (valueId, value) =>
2324
+ const setValue = (valueId, value, skipMiddleware) =>
2144
2325
  fluentTransaction(
2145
2326
  (valueId2) =>
2146
2327
  ifNotUndefined(
@@ -2148,27 +2329,40 @@ const createStore = () => {
2148
2329
  valueId2,
2149
2330
  isFunction(value) ? value(getValue(valueId2)) : value,
2150
2331
  ),
2151
- (validValue) => setValidValue(valueId2, validValue),
2332
+ (validValue) => setValidValue(valueId2, validValue, skipMiddleware),
2152
2333
  ),
2153
2334
  valueId,
2154
2335
  );
2155
2336
  const applyChanges = (changes) =>
2156
- fluentTransaction(() => {
2157
- objMap(changes[0], (table, tableId) =>
2158
- isUndefined(table)
2159
- ? delTable(tableId)
2160
- : objMap(table, (row, rowId) =>
2161
- isUndefined(row)
2162
- ? delRow(tableId, rowId)
2163
- : objMap(row, (cell, cellId) =>
2164
- setOrDelCell(store, tableId, rowId, cellId, cell),
2165
- ),
2166
- ),
2167
- );
2168
- objMap(changes[1], (value, valueId) =>
2169
- setOrDelValue(store, valueId, value),
2170
- );
2171
- });
2337
+ fluentTransaction(() =>
2338
+ ifTransformed(
2339
+ changes,
2340
+ () =>
2341
+ ifNotUndefined(
2342
+ middleware[13],
2343
+ (willApplyChanges) =>
2344
+ whileMutating(() => willApplyChanges(structuredClone(changes))),
2345
+ () => changes,
2346
+ ),
2347
+ (changes2) => {
2348
+ objMap(changes2[0], (table, tableId) =>
2349
+ isUndefined(table)
2350
+ ? delTable(tableId)
2351
+ : objMap(table, (row, rowId) =>
2352
+ isUndefined(row)
2353
+ ? delRow(tableId, rowId)
2354
+ : objMap(row, (cell, cellId) =>
2355
+ setOrDelCell(tableId, rowId, cellId, cell),
2356
+ ),
2357
+ ),
2358
+ );
2359
+ objMap(changes2[1], (value, valueId) =>
2360
+ setOrDelValue(valueId, value),
2361
+ );
2362
+ },
2363
+ contentOrChangesIsEqual,
2364
+ ),
2365
+ );
2172
2366
  const setTablesJson = (tablesJson) => {
2173
2367
  tryCatch(() => setOrDelTables(jsonParse(tablesJson)));
2174
2368
  return store;
@@ -2215,7 +2409,12 @@ const createStore = () => {
2215
2409
  setTablesSchema(tablesSchema);
2216
2410
  setValuesSchema(valuesSchema);
2217
2411
  });
2218
- const delTables = () => fluentTransaction(() => setValidTables({}));
2412
+ const delTables = () =>
2413
+ fluentTransaction(() =>
2414
+ (whileMutating(() => middleware[7]?.()) ?? true)
2415
+ ? setValidTables({}, true)
2416
+ : 0,
2417
+ );
2219
2418
  const delTable = (tableId) =>
2220
2419
  fluentTransaction(
2221
2420
  (tableId2) =>
@@ -2233,7 +2432,7 @@ const createStore = () => {
2233
2432
  tableId,
2234
2433
  rowId,
2235
2434
  );
2236
- const delCell = (tableId, rowId, cellId, forceDel) =>
2435
+ const delCell = (tableId, rowId, cellId, forceDel, skipMiddleware) =>
2237
2436
  fluentTransaction(
2238
2437
  (tableId2, rowId2, cellId2) =>
2239
2438
  ifNotUndefined(mapGet(tablesMap, tableId2), (tableMap) =>
@@ -2246,6 +2445,7 @@ const createStore = () => {
2246
2445
  rowMap,
2247
2446
  cellId2,
2248
2447
  forceDel,
2448
+ skipMiddleware,
2249
2449
  )
2250
2450
  : 0,
2251
2451
  ),
@@ -2254,11 +2454,18 @@ const createStore = () => {
2254
2454
  rowId,
2255
2455
  cellId,
2256
2456
  );
2257
- const delValues = () => fluentTransaction(() => setValidValues({}));
2258
- const delValue = (valueId) =>
2457
+ const delValues = () =>
2458
+ fluentTransaction(() =>
2459
+ (whileMutating(() => middleware[11]?.()) ?? true)
2460
+ ? setValidValues({}, true)
2461
+ : 0,
2462
+ );
2463
+ const delValue = (valueId, skipMiddleware) =>
2259
2464
  fluentTransaction(
2260
2465
  (valueId2) =>
2261
- collHas(valuesMap, valueId2) ? delValidValue(valueId2) : 0,
2466
+ collHas(valuesMap, valueId2)
2467
+ ? delValidValue(valueId2, skipMiddleware)
2468
+ : 0,
2262
2469
  valueId,
2263
2470
  );
2264
2471
  const delTablesSchema = () =>
@@ -2340,25 +2547,27 @@ const createStore = () => {
2340
2547
  transactions--;
2341
2548
  if (transactions == 0) {
2342
2549
  transactions = 1;
2343
- callInvalidCellListeners(1);
2344
- if (!collIsEmpty(changedCells)) {
2345
- callTabularListenersForChanges(1);
2346
- }
2347
- callInvalidValueListeners(1);
2348
- if (!collIsEmpty(changedValues)) {
2349
- callValuesListenersForChanges(1);
2350
- }
2550
+ whileMutating(() => {
2551
+ callInvalidCellListeners(1);
2552
+ if (!collIsEmpty(changedCells)) {
2553
+ callTabularListenersForChanges(1);
2554
+ }
2555
+ callInvalidValueListeners(1);
2556
+ if (!collIsEmpty(changedValues)) {
2557
+ callValuesListenersForChanges(1);
2558
+ }
2559
+ });
2351
2560
  if (doRollback?.(store)) {
2352
2561
  collForEach(changedCells, (table, tableId) =>
2353
2562
  collForEach(table, (row, rowId) =>
2354
2563
  collForEach(row, ([oldCell], cellId) =>
2355
- setOrDelCell(store, tableId, rowId, cellId, oldCell),
2564
+ setOrDelCell(tableId, rowId, cellId, oldCell, true),
2356
2565
  ),
2357
2566
  ),
2358
2567
  );
2359
2568
  collClear(changedCells);
2360
2569
  collForEach(changedValues, ([oldValue], valueId) =>
2361
- setOrDelValue(store, valueId, oldValue),
2570
+ setOrDelValue(valueId, oldValue, true),
2362
2571
  );
2363
2572
  collClear(changedValues);
2364
2573
  }
@@ -2485,6 +2694,38 @@ const createStore = () => {
2485
2694
  collSize2(startTransactionListeners) +
2486
2695
  pairCollSize2(finishTransactionListeners),
2487
2696
  });
2697
+ const setMiddleware = (
2698
+ willSetContent,
2699
+ willSetTables,
2700
+ willSetTable,
2701
+ willSetRow,
2702
+ willSetCell,
2703
+ willSetValues,
2704
+ willSetValue,
2705
+ willDelTables,
2706
+ willDelTable,
2707
+ willDelRow,
2708
+ willDelCell,
2709
+ willDelValues,
2710
+ willDelValue,
2711
+ willApplyChanges,
2712
+ ) =>
2713
+ (middleware = [
2714
+ willSetContent,
2715
+ willSetTables,
2716
+ willSetTable,
2717
+ willSetRow,
2718
+ willSetCell,
2719
+ willSetValues,
2720
+ willSetValue,
2721
+ willDelTables,
2722
+ willDelTable,
2723
+ willDelRow,
2724
+ willDelCell,
2725
+ willDelValues,
2726
+ willDelValue,
2727
+ willApplyChanges,
2728
+ ]);
2488
2729
  const setInternalListeners = (
2489
2730
  preStartTransaction,
2490
2731
  preFinishTransaction,
@@ -2578,6 +2819,9 @@ const createStore = () => {
2578
2819
  addListener,
2579
2820
  callListeners,
2580
2821
  setInternalListeners,
2822
+ setMiddleware,
2823
+ setOrDelCell,
2824
+ setOrDelValue,
2581
2825
  };
2582
2826
  objMap(
2583
2827
  {
@@ -2714,6 +2958,7 @@ const createMergeableStore = (uniqueId, getNow) => {
2714
2958
  let listeningToRawStoreChanges = 1;
2715
2959
  let contentStampMap = newContentStampMap();
2716
2960
  let defaultingContent = 0;
2961
+ let mutated = 0;
2717
2962
  const touchedCells = mapNew();
2718
2963
  const touchedValues = setNew();
2719
2964
  const [getNextHlc, seenHlc] = getHlcFunctions(uniqueId, getNow);
@@ -2840,12 +3085,15 @@ const createMergeableStore = (uniqueId, getNow) => {
2840
3085
  collClear(touchedCells);
2841
3086
  collClear(touchedValues);
2842
3087
  };
2843
- const cellChanged = (tableId, rowId, cellId, newCell) => {
3088
+ const cellChanged = (tableId, rowId, cellId, newCell, mutating) => {
2844
3089
  setAdd(
2845
3090
  mapEnsure(mapEnsure(touchedCells, tableId, mapNew), rowId, setNew),
2846
3091
  cellId,
2847
3092
  );
2848
- if (listeningToRawStoreChanges) {
3093
+ if (listeningToRawStoreChanges || mutating) {
3094
+ if (mutating) {
3095
+ mutated = 1;
3096
+ }
2849
3097
  mergeContentOrChanges([
2850
3098
  [
2851
3099
  {
@@ -2868,9 +3116,12 @@ const createMergeableStore = (uniqueId, getNow) => {
2868
3116
  ]);
2869
3117
  }
2870
3118
  };
2871
- const valueChanged = (valueId, newValue) => {
3119
+ const valueChanged = (valueId, newValue, mutating) => {
2872
3120
  setAdd(touchedValues, valueId);
2873
- if (listeningToRawStoreChanges) {
3121
+ if (listeningToRawStoreChanges || mutating) {
3122
+ if (mutating) {
3123
+ mutated = 1;
3124
+ }
2874
3125
  mergeContentOrChanges([
2875
3126
  [{}],
2876
3127
  [
@@ -3088,6 +3339,11 @@ const createMergeableStore = (uniqueId, getNow) => {
3088
3339
  mergeableStore2.applyMergeableChanges(mergeableChanges);
3089
3340
  return applyMergeableChanges(mergeableChanges2);
3090
3341
  };
3342
+ const hadMutated = () => {
3343
+ const result = mutated;
3344
+ mutated = 0;
3345
+ return result;
3346
+ };
3091
3347
  const mergeableStore = {
3092
3348
  getMergeableContent,
3093
3349
  getMergeableContentHashes,
@@ -3104,6 +3360,8 @@ const createMergeableStore = (uniqueId, getNow) => {
3104
3360
  getTransactionMergeableChanges,
3105
3361
  applyMergeableChanges,
3106
3362
  merge,
3363
+ // only used internally by other modules
3364
+ hadMutated,
3107
3365
  };
3108
3366
  store.setInternalListeners(
3109
3367
  preStartTransaction,
@@ -3120,7 +3378,8 @@ const createMergeableStore = (uniqueId, getNow) => {
3120
3378
  strStartsWith(name, DEL) ||
3121
3379
  strStartsWith(name, 'apply') ||
3122
3380
  strEndsWith(name, TRANSACTION) ||
3123
- name == 'call' + LISTENER
3381
+ name == 'call' + LISTENER ||
3382
+ name == 'use'
3124
3383
  ? (...args) => {
3125
3384
  method(...args);
3126
3385
  return mergeableStore;
@@ -3313,6 +3572,115 @@ const createMetrics = getCreateFunction((store) => {
3313
3572
  return objFreeze(metrics);
3314
3573
  });
3315
3574
 
3575
+ const reduceCallbacks = (callbacks, thing, ...ids) =>
3576
+ arrayReduce(
3577
+ callbacks,
3578
+ (current, callback) =>
3579
+ isUndefined(current) ? current : callback(...ids, current),
3580
+ thing,
3581
+ );
3582
+ const everyCallback = (callbacks, ...ids) =>
3583
+ arrayEvery(callbacks, (callback) => callback(...ids));
3584
+ const createMiddleware = getCreateFunction((store) => {
3585
+ const fluent = (actions) => {
3586
+ actions();
3587
+ return middleware;
3588
+ };
3589
+ const addCallback = (callbacks) => (callback) =>
3590
+ fluent(() => arrayPush(callbacks, callback));
3591
+ const willSetContentCallbacks = [];
3592
+ const willSetTablesCallbacks = [];
3593
+ const willSetTableCallbacks = [];
3594
+ const willSetRowCallbacks = [];
3595
+ const willSetCellCallbacks = [];
3596
+ const willSetValuesCallbacks = [];
3597
+ const willSetValueCallbacks = [];
3598
+ const willDelTablesCallbacks = [];
3599
+ const willDelTableCallbacks = [];
3600
+ const willDelRowCallbacks = [];
3601
+ const willDelCellCallbacks = [];
3602
+ const willDelValuesCallbacks = [];
3603
+ const willDelValueCallbacks = [];
3604
+ const willApplyChangesCallbacks = [];
3605
+ const willSetContent = (content) =>
3606
+ reduceCallbacks(willSetContentCallbacks, content);
3607
+ const willSetTables = (tables) =>
3608
+ reduceCallbacks(willSetTablesCallbacks, tables);
3609
+ const willSetTable = (tableId, table) =>
3610
+ reduceCallbacks(willSetTableCallbacks, table, tableId);
3611
+ const willSetRow = (tableId, rowId, row) =>
3612
+ reduceCallbacks(willSetRowCallbacks, row, tableId, rowId);
3613
+ const willSetCell = (tableId, rowId, cellId, cell) =>
3614
+ reduceCallbacks(willSetCellCallbacks, cell, tableId, rowId, cellId);
3615
+ const willSetValues = (values) =>
3616
+ reduceCallbacks(willSetValuesCallbacks, values);
3617
+ const willSetValue = (valueId, value) =>
3618
+ reduceCallbacks(willSetValueCallbacks, value, valueId);
3619
+ const willDelTables = () => everyCallback(willDelTablesCallbacks);
3620
+ const willDelTable = (tableId) =>
3621
+ everyCallback(willDelTableCallbacks, tableId);
3622
+ const willDelRow = (tableId, rowId) =>
3623
+ everyCallback(willDelRowCallbacks, tableId, rowId);
3624
+ const willDelCell = (tableId, rowId, cellId) =>
3625
+ everyCallback(willDelCellCallbacks, tableId, rowId, cellId);
3626
+ const willDelValues = () => everyCallback(willDelValuesCallbacks);
3627
+ const willDelValue = (valueId) =>
3628
+ everyCallback(willDelValueCallbacks, valueId);
3629
+ const willApplyChanges = (changes) =>
3630
+ reduceCallbacks(willApplyChangesCallbacks, changes);
3631
+ const getStore = () => store;
3632
+ const addWillSetContentCallback = addCallback(willSetContentCallbacks);
3633
+ const addWillSetTablesCallback = addCallback(willSetTablesCallbacks);
3634
+ const addWillSetTableCallback = addCallback(willSetTableCallbacks);
3635
+ const addWillSetRowCallback = addCallback(willSetRowCallbacks);
3636
+ const addWillSetCellCallback = addCallback(willSetCellCallbacks);
3637
+ const addWillSetValuesCallback = addCallback(willSetValuesCallbacks);
3638
+ const addWillSetValueCallback = addCallback(willSetValueCallbacks);
3639
+ const addWillDelTablesCallback = addCallback(willDelTablesCallbacks);
3640
+ const addWillDelTableCallback = addCallback(willDelTableCallbacks);
3641
+ const addWillDelRowCallback = addCallback(willDelRowCallbacks);
3642
+ const addWillDelCellCallback = addCallback(willDelCellCallbacks);
3643
+ const addWillDelValuesCallback = addCallback(willDelValuesCallbacks);
3644
+ const addWillDelValueCallback = addCallback(willDelValueCallbacks);
3645
+ const addWillApplyChangesCallback = addCallback(willApplyChangesCallbacks);
3646
+ const destroy = () => {};
3647
+ const middleware = objFreeze({
3648
+ getStore,
3649
+ addWillSetContentCallback,
3650
+ addWillSetTablesCallback,
3651
+ addWillSetTableCallback,
3652
+ addWillSetRowCallback,
3653
+ addWillSetCellCallback,
3654
+ addWillSetValuesCallback,
3655
+ addWillSetValueCallback,
3656
+ addWillDelTablesCallback,
3657
+ addWillDelTableCallback,
3658
+ addWillDelRowCallback,
3659
+ addWillDelCellCallback,
3660
+ addWillDelValuesCallback,
3661
+ addWillDelValueCallback,
3662
+ addWillApplyChangesCallback,
3663
+ destroy,
3664
+ });
3665
+ store.setMiddleware(
3666
+ willSetContent,
3667
+ willSetTables,
3668
+ willSetTable,
3669
+ willSetRow,
3670
+ willSetCell,
3671
+ willSetValues,
3672
+ willSetValue,
3673
+ willDelTables,
3674
+ willDelTable,
3675
+ willDelRow,
3676
+ willDelCell,
3677
+ willDelValues,
3678
+ willDelValue,
3679
+ willApplyChanges,
3680
+ );
3681
+ return middleware;
3682
+ });
3683
+
3316
3684
  const Status = {
3317
3685
  Idle: 0 /* Idle */,
3318
3686
  Loading: 1 /* Loading */,
@@ -3407,6 +3775,11 @@ const createCustomPersister = (
3407
3775
  ? store.applyChanges
3408
3776
  : store.setContent)(contentOrChanges);
3409
3777
  };
3778
+ const saveAfterMutated = async () => {
3779
+ if (isAutoSaving() && store.hadMutated?.()) {
3780
+ await save();
3781
+ }
3782
+ };
3410
3783
  const load = async (initialContent) => {
3411
3784
  /* istanbul ignore else */
3412
3785
  if (status != 2 /* Saving */) {
@@ -3431,6 +3804,7 @@ const createCustomPersister = (
3431
3804
  },
3432
3805
  );
3433
3806
  setStatus(0 /* Idle */);
3807
+ await saveAfterMutated();
3434
3808
  });
3435
3809
  }
3436
3810
  return persister;
@@ -3449,6 +3823,7 @@ const createCustomPersister = (
3449
3823
  loads++;
3450
3824
  setContentOrChanges(changes ?? content);
3451
3825
  setStatus(0 /* Idle */);
3826
+ await saveAfterMutated();
3452
3827
  }
3453
3828
  } else {
3454
3829
  await load();
@@ -4667,12 +5042,9 @@ const createDurableObjectStoragePersister = (
4667
5042
  storagePrefix + type + slice(jsonStringWithUndefined(ids), 1, -1);
4668
5043
  const deconstructKey = (key) => {
4669
5044
  if (strStartsWith(key, storagePrefix)) {
4670
- const type = slice(key, storagePrefix.length, 1);
5045
+ const type = slice(key, size(storagePrefix), size(storagePrefix) + 1);
4671
5046
  return type == T || type == V
4672
- ? [
4673
- type,
4674
- ...JSON.parse('[' + slice(key, storagePrefix.length + 1) + ']'),
4675
- ]
5047
+ ? [type, ...JSON.parse('[' + slice(key, size(storagePrefix) + 1) + ']')]
4676
5048
  : void 0;
4677
5049
  }
4678
5050
  };
@@ -4721,7 +5093,9 @@ const createDurableObjectStoragePersister = (
4721
5093
  : 0,
4722
5094
  ),
4723
5095
  );
4724
- return [tables, values];
5096
+ return objIsEmpty(tables[0]) && objIsEmpty(values[0])
5097
+ ? void 0
5098
+ : [tables, values];
4725
5099
  };
4726
5100
  const setPersisted = async (
4727
5101
  getContent,
@@ -4959,13 +5333,17 @@ const SET_CHANGES = 's';
4959
5333
  const STORE_PATH = '/store';
4960
5334
  const PUT = 'PUT';
4961
5335
  const construct = (prefix, type, payload) =>
4962
- prefix + type + (isString(payload) ? payload : jsonStringWithMap(payload));
5336
+ prefix +
5337
+ type +
5338
+ (isString(payload) ? payload : jsonStringWithUndefined(payload));
4963
5339
  const deconstruct = (prefix, message, stringified) => {
4964
5340
  const prefixSize = size(prefix);
4965
5341
  return strStartsWith(message, prefix)
4966
5342
  ? [
4967
5343
  message[prefixSize],
4968
- (stringified ? jsonParse : String)(slice(message, prefixSize + 1)),
5344
+ (stringified ? jsonParseWithUndefined : String)(
5345
+ slice(message, prefixSize + 1),
5346
+ ),
4969
5347
  ]
4970
5348
  : void 0;
4971
5349
  };
@@ -6138,8 +6516,7 @@ const createQueries = getCreateFunction((store) => {
6138
6516
  selectJoinWhereStore.transaction(() =>
6139
6517
  arrayEvery(wheres, (where2) => where2(getTableCell))
6140
6518
  ? mapForEach(selects, (asCellId, tableCellGetter) =>
6141
- setOrDelCell(
6142
- selectJoinWhereStore,
6519
+ selectJoinWhereStore.setOrDelCell(
6143
6520
  queryId,
6144
6521
  rootRowId,
6145
6522
  asCellId,
@@ -11647,6 +12024,7 @@ export {
11647
12024
  createLocalSynchronizer,
11648
12025
  createMergeableStore,
11649
12026
  createMetrics,
12027
+ createMiddleware,
11650
12028
  createOpfsPersister,
11651
12029
  createPartyKitPersister,
11652
12030
  createPglitePersister,