tinybase 4.0.0-beta.1 → 4.0.0-beta.2

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 (197) hide show
  1. package/bin/cli.js +1 -1
  2. package/lib/checkpoints.js +1 -1
  3. package/lib/checkpoints.js.gz +0 -0
  4. package/lib/cjs/checkpoints.cjs +1 -1
  5. package/lib/cjs/checkpoints.cjs.gz +0 -0
  6. package/lib/cjs/indexes.cjs +1 -1
  7. package/lib/cjs/indexes.cjs.gz +0 -0
  8. package/lib/cjs/metrics.cjs +1 -1
  9. package/lib/cjs/metrics.cjs.gz +0 -0
  10. package/lib/cjs/persister-browser.cjs +1 -1
  11. package/lib/cjs/persister-browser.cjs.gz +0 -0
  12. package/lib/cjs/persister-file.cjs +1 -1
  13. package/lib/cjs/persister-file.cjs.gz +0 -0
  14. package/lib/cjs/persister-remote.cjs +1 -1
  15. package/lib/cjs/persister-remote.cjs.gz +0 -0
  16. package/lib/cjs/persister-yjs.cjs +1 -1
  17. package/lib/cjs/persister-yjs.cjs.gz +0 -0
  18. package/lib/cjs/persisters.cjs +1 -1
  19. package/lib/cjs/persisters.cjs.gz +0 -0
  20. package/lib/cjs/queries.cjs +1 -1
  21. package/lib/cjs/queries.cjs.gz +0 -0
  22. package/lib/cjs/relationships.cjs +1 -1
  23. package/lib/cjs/relationships.cjs.gz +0 -0
  24. package/lib/cjs/store.cjs +1 -1
  25. package/lib/cjs/store.cjs.gz +0 -0
  26. package/lib/cjs/tinybase.cjs +1 -1
  27. package/lib/cjs/tinybase.cjs.gz +0 -0
  28. package/lib/cjs/tools.cjs +1 -1
  29. package/lib/cjs/tools.cjs.gz +0 -0
  30. package/lib/cjs/ui-react.cjs +1 -1
  31. package/lib/cjs/ui-react.cjs.gz +0 -0
  32. package/lib/cjs-es6/checkpoints.cjs +1 -1
  33. package/lib/cjs-es6/checkpoints.cjs.gz +0 -0
  34. package/lib/cjs-es6/indexes.cjs +1 -1
  35. package/lib/cjs-es6/indexes.cjs.gz +0 -0
  36. package/lib/cjs-es6/metrics.cjs +1 -1
  37. package/lib/cjs-es6/metrics.cjs.gz +0 -0
  38. package/lib/cjs-es6/persister-browser.cjs +1 -1
  39. package/lib/cjs-es6/persister-browser.cjs.gz +0 -0
  40. package/lib/cjs-es6/persister-file.cjs +1 -1
  41. package/lib/cjs-es6/persister-file.cjs.gz +0 -0
  42. package/lib/cjs-es6/persister-remote.cjs +1 -1
  43. package/lib/cjs-es6/persister-remote.cjs.gz +0 -0
  44. package/lib/cjs-es6/persister-yjs.cjs +1 -1
  45. package/lib/cjs-es6/persister-yjs.cjs.gz +0 -0
  46. package/lib/cjs-es6/persisters.cjs +1 -1
  47. package/lib/cjs-es6/persisters.cjs.gz +0 -0
  48. package/lib/cjs-es6/queries.cjs +1 -1
  49. package/lib/cjs-es6/queries.cjs.gz +0 -0
  50. package/lib/cjs-es6/relationships.cjs +1 -1
  51. package/lib/cjs-es6/relationships.cjs.gz +0 -0
  52. package/lib/cjs-es6/store.cjs +1 -1
  53. package/lib/cjs-es6/store.cjs.gz +0 -0
  54. package/lib/cjs-es6/tinybase.cjs +1 -1
  55. package/lib/cjs-es6/tinybase.cjs.gz +0 -0
  56. package/lib/cjs-es6/tools.cjs +1 -1
  57. package/lib/cjs-es6/tools.cjs.gz +0 -0
  58. package/lib/cjs-es6/ui-react.cjs +1 -1
  59. package/lib/cjs-es6/ui-react.cjs.gz +0 -0
  60. package/lib/debug/checkpoints.js +3 -3
  61. package/lib/debug/indexes.js +3 -3
  62. package/lib/debug/metrics.js +3 -3
  63. package/lib/debug/persister-browser.js +38 -39
  64. package/lib/debug/persister-file.js +37 -37
  65. package/lib/debug/persister-remote.js +37 -34
  66. package/lib/debug/persister-yjs.js +225 -40
  67. package/lib/debug/persisters.js +36 -33
  68. package/lib/debug/queries.js +5 -5
  69. package/lib/debug/relationships.js +3 -3
  70. package/lib/debug/store.js +129 -94
  71. package/lib/debug/tinybase.js +165 -125
  72. package/lib/debug/tools.js +9 -9
  73. package/lib/es6/checkpoints.js +1 -1
  74. package/lib/es6/checkpoints.js.gz +0 -0
  75. package/lib/es6/indexes.js +1 -1
  76. package/lib/es6/indexes.js.gz +0 -0
  77. package/lib/es6/metrics.js +1 -1
  78. package/lib/es6/metrics.js.gz +0 -0
  79. package/lib/es6/persister-browser.js +1 -1
  80. package/lib/es6/persister-browser.js.gz +0 -0
  81. package/lib/es6/persister-file.js +1 -1
  82. package/lib/es6/persister-file.js.gz +0 -0
  83. package/lib/es6/persister-remote.js +1 -1
  84. package/lib/es6/persister-remote.js.gz +0 -0
  85. package/lib/es6/persister-yjs.js +1 -1
  86. package/lib/es6/persister-yjs.js.gz +0 -0
  87. package/lib/es6/persisters.js +1 -1
  88. package/lib/es6/persisters.js.gz +0 -0
  89. package/lib/es6/queries.js +1 -1
  90. package/lib/es6/queries.js.gz +0 -0
  91. package/lib/es6/relationships.js +1 -1
  92. package/lib/es6/relationships.js.gz +0 -0
  93. package/lib/es6/store.js +1 -1
  94. package/lib/es6/store.js.gz +0 -0
  95. package/lib/es6/tinybase.js +1 -1
  96. package/lib/es6/tinybase.js.gz +0 -0
  97. package/lib/es6/tools.js +1 -1
  98. package/lib/es6/tools.js.gz +0 -0
  99. package/lib/es6/ui-react.js +1 -1
  100. package/lib/es6/ui-react.js.gz +0 -0
  101. package/lib/indexes.js +1 -1
  102. package/lib/indexes.js.gz +0 -0
  103. package/lib/metrics.js +1 -1
  104. package/lib/metrics.js.gz +0 -0
  105. package/lib/persister-browser.js +1 -1
  106. package/lib/persister-browser.js.gz +0 -0
  107. package/lib/persister-file.js +1 -1
  108. package/lib/persister-file.js.gz +0 -0
  109. package/lib/persister-remote.js +1 -1
  110. package/lib/persister-remote.js.gz +0 -0
  111. package/lib/persister-yjs.js +1 -1
  112. package/lib/persister-yjs.js.gz +0 -0
  113. package/lib/persisters.js +1 -1
  114. package/lib/persisters.js.gz +0 -0
  115. package/lib/queries.js +1 -1
  116. package/lib/queries.js.gz +0 -0
  117. package/lib/relationships.js +1 -1
  118. package/lib/relationships.js.gz +0 -0
  119. package/lib/store.js +1 -1
  120. package/lib/store.js.gz +0 -0
  121. package/lib/tinybase.js +1 -1
  122. package/lib/tinybase.js.gz +0 -0
  123. package/lib/tools.js +1 -1
  124. package/lib/tools.js.gz +0 -0
  125. package/lib/types/persister-yjs.d.ts +70 -8
  126. package/lib/types/persisters.d.ts +42 -17
  127. package/lib/types/queries.d.ts +52 -52
  128. package/lib/types/store.d.ts +399 -145
  129. package/lib/types/tools.d.ts +16 -16
  130. package/lib/types/ui-react.d.ts +56 -47
  131. package/lib/types/with-schemas/internal/ui-react.d.ts +2 -2
  132. package/lib/types/with-schemas/persister-yjs.d.ts +72 -9
  133. package/lib/types/with-schemas/persisters.d.ts +59 -18
  134. package/lib/types/with-schemas/queries.d.ts +52 -52
  135. package/lib/types/with-schemas/store.d.ts +480 -163
  136. package/lib/types/with-schemas/tools.d.ts +16 -16
  137. package/lib/types/with-schemas/ui-react.d.ts +54 -45
  138. package/lib/ui-react.js +1 -1
  139. package/lib/ui-react.js.gz +0 -0
  140. package/lib/umd/checkpoints.js +1 -1
  141. package/lib/umd/checkpoints.js.gz +0 -0
  142. package/lib/umd/indexes.js +1 -1
  143. package/lib/umd/indexes.js.gz +0 -0
  144. package/lib/umd/metrics.js +1 -1
  145. package/lib/umd/metrics.js.gz +0 -0
  146. package/lib/umd/persister-browser.js +1 -1
  147. package/lib/umd/persister-browser.js.gz +0 -0
  148. package/lib/umd/persister-file.js +1 -1
  149. package/lib/umd/persister-file.js.gz +0 -0
  150. package/lib/umd/persister-remote.js +1 -1
  151. package/lib/umd/persister-remote.js.gz +0 -0
  152. package/lib/umd/persister-yjs.js +1 -1
  153. package/lib/umd/persister-yjs.js.gz +0 -0
  154. package/lib/umd/persisters.js +1 -1
  155. package/lib/umd/persisters.js.gz +0 -0
  156. package/lib/umd/queries.js +1 -1
  157. package/lib/umd/queries.js.gz +0 -0
  158. package/lib/umd/relationships.js +1 -1
  159. package/lib/umd/relationships.js.gz +0 -0
  160. package/lib/umd/store.js +1 -1
  161. package/lib/umd/store.js.gz +0 -0
  162. package/lib/umd/tinybase.js +1 -1
  163. package/lib/umd/tinybase.js.gz +0 -0
  164. package/lib/umd/tools.js +1 -1
  165. package/lib/umd/tools.js.gz +0 -0
  166. package/lib/umd/ui-react.js +1 -1
  167. package/lib/umd/ui-react.js.gz +0 -0
  168. package/lib/umd-es6/checkpoints.js +1 -1
  169. package/lib/umd-es6/checkpoints.js.gz +0 -0
  170. package/lib/umd-es6/indexes.js +1 -1
  171. package/lib/umd-es6/indexes.js.gz +0 -0
  172. package/lib/umd-es6/metrics.js +1 -1
  173. package/lib/umd-es6/metrics.js.gz +0 -0
  174. package/lib/umd-es6/persister-browser.js +1 -1
  175. package/lib/umd-es6/persister-browser.js.gz +0 -0
  176. package/lib/umd-es6/persister-file.js +1 -1
  177. package/lib/umd-es6/persister-file.js.gz +0 -0
  178. package/lib/umd-es6/persister-remote.js +1 -1
  179. package/lib/umd-es6/persister-remote.js.gz +0 -0
  180. package/lib/umd-es6/persister-yjs.js +1 -1
  181. package/lib/umd-es6/persister-yjs.js.gz +0 -0
  182. package/lib/umd-es6/persisters.js +1 -1
  183. package/lib/umd-es6/persisters.js.gz +0 -0
  184. package/lib/umd-es6/queries.js +1 -1
  185. package/lib/umd-es6/queries.js.gz +0 -0
  186. package/lib/umd-es6/relationships.js +1 -1
  187. package/lib/umd-es6/relationships.js.gz +0 -0
  188. package/lib/umd-es6/store.js +1 -1
  189. package/lib/umd-es6/store.js.gz +0 -0
  190. package/lib/umd-es6/tinybase.js +1 -1
  191. package/lib/umd-es6/tinybase.js.gz +0 -0
  192. package/lib/umd-es6/tools.js +1 -1
  193. package/lib/umd-es6/tools.js.gz +0 -0
  194. package/lib/umd-es6/ui-react.js +1 -1
  195. package/lib/umd-es6/ui-react.js.gz +0 -0
  196. package/package.json +13 -13
  197. package/readme.md +2 -2
@@ -20,6 +20,9 @@ const isString = (thing) => getTypeOf(thing) == STRING;
20
20
  const isArray = (thing) => Array.isArray(thing);
21
21
  const test = (regex, subject) => regex.test(subject);
22
22
 
23
+ const object = Object;
24
+ const objFreeze = object.freeze;
25
+
23
26
  const collSizeN = (collSizer) => (coll) =>
24
27
  arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
25
28
  const collSize = (coll) => coll.size;
@@ -317,9 +320,6 @@ const getListenerFunctions = (getThing) => {
317
320
  return [addListener, callListeners, delListener, callListener];
318
321
  };
319
322
 
320
- const object = Object;
321
- const objFreeze = object.freeze;
322
-
323
323
  const createRelationships = getCreateFunction((store) => {
324
324
  const remoteTableIds = mapNew();
325
325
  const remoteRowIdListeners = mapNew();
@@ -32,7 +32,6 @@ const arrayMap = (array, cb) => array.map(cb);
32
32
  const arrayLength = (array) => array.length;
33
33
  const arrayIsEmpty = (array) => arrayLength(array) == 0;
34
34
  const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
35
- const arrayFilter = (array, cb) => array.filter(cb);
36
35
  const arraySlice = (array, start, end) => array.slice(start, end);
37
36
  const arrayPush = (array, ...values) => array.push(...values);
38
37
  const arrayShift = (array) => array.shift();
@@ -61,6 +60,19 @@ const isFunction = (thing) => getTypeOf(thing) == FUNCTION;
61
60
  const isArray = (thing) => Array.isArray(thing);
62
61
  const test = (regex, subject) => regex.test(subject);
63
62
 
63
+ const object = Object;
64
+ const objIds = object.keys;
65
+ const objFrozen = object.isFrozen;
66
+ const objFreeze = object.freeze;
67
+ const isObject = (obj) =>
68
+ isInstanceOf(obj, object) && obj.constructor == object;
69
+ const objGet = (obj, id) => ifNotUndefined(obj, (obj2) => obj2[id]);
70
+ const objHas = (obj, id) => !isUndefined(objGet(obj, id));
71
+ const objDel = (obj, id) => delete obj[id];
72
+ const objMap = (obj, cb) =>
73
+ arrayMap(object.entries(obj), ([id, value]) => cb(value, id));
74
+ const objIsEmpty = (obj) => isObject(obj) && arrayIsEmpty(objIds(obj));
75
+
64
76
  const collSizeN = (collSizer) => (coll) =>
65
77
  arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
66
78
  const collSize = (coll) => coll.size;
@@ -89,23 +101,33 @@ const mapEnsure = (map, key, getDefaultValue) => {
89
101
  }
90
102
  return mapGet(map, key);
91
103
  };
92
- const mapToObj = (map, childMapper, childExclude) => {
104
+ const mapToObj = (map, mapValue, excludeValue) => {
93
105
  const obj = {};
94
- const mapper = childMapper ?? ((mapValue) => mapValue);
95
- collForEach(map, (value, key) =>
96
- ifNotUndefined(mapper(value), (mappedValue) =>
97
- childExclude?.(mappedValue) ? 0 : (obj[key] = mappedValue),
98
- ),
99
- );
106
+ collForEach(map, (value, id) => {
107
+ const mappedValue = mapValue ? mapValue(value, id) : value;
108
+ excludeValue?.(mappedValue, value) ? 0 : (obj[id] = mappedValue);
109
+ });
100
110
  return obj;
101
111
  };
102
- const mapClone = (map, childMapper) => {
112
+ const mapToObj2 = (map, mapValue, excludeValue) =>
113
+ mapToObj(
114
+ map,
115
+ (childMap) => mapToObj(childMap, mapValue, excludeValue),
116
+ objIsEmpty,
117
+ );
118
+ const mapToObj3 = (map, mapValue, excludeValue) =>
119
+ mapToObj(
120
+ map,
121
+ (childMap) => mapToObj2(childMap, mapValue, excludeValue),
122
+ objIsEmpty,
123
+ );
124
+ const mapClone = (map, mapValue) => {
103
125
  const map2 = mapNew();
104
- const mapper = childMapper ?? ((mapValue) => mapValue);
105
- collForEach(map, (value, key) => map2.set(key, mapper(value)));
126
+ collForEach(map, (value, key) => map2.set(key, mapValue?.(value) ?? value));
106
127
  return map2;
107
128
  };
108
129
  const mapClone2 = (map) => mapClone(map, mapClone);
130
+ const mapClone3 = (map) => mapClone(map, mapClone2);
109
131
  const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
110
132
  ifNotUndefined(
111
133
  (ensureLeaf ? mapEnsure : mapGet)(
@@ -220,22 +242,11 @@ const getListenerFunctions = (getThing) => {
220
242
  return [addListener, callListeners, delListener, callListener];
221
243
  };
222
244
 
223
- const object = Object;
224
- const objIds = object.keys;
225
- const objFrozen = object.isFrozen;
226
- const objFreeze = object.freeze;
227
- const isObject = (obj) =>
228
- isInstanceOf(obj, object) && obj.constructor == object;
229
- const objGet = (obj, id) => ifNotUndefined(obj, (obj2) => obj2[id]);
230
- const objHas = (obj, id) => !isUndefined(objGet(obj, id));
231
- const objDel = (obj, id) => delete obj[id];
232
- const objMap = (obj, cb) =>
233
- arrayMap(object.entries(obj), ([id, value]) => cb(value, id));
234
- const objIsEmpty = (obj) => isObject(obj) && arrayIsEmpty(objIds(obj));
235
-
236
245
  const pairNew = (value) => [value, value];
237
246
  const pairCollSize2 = (pair, func = collSize2) => func(pair[0]) + func(pair[1]);
238
247
  const pairNewMap = () => [mapNew(), mapNew()];
248
+ const pairClone = (array) => [...array];
249
+ const pairIsEqual = ([entry1, entry2]) => entry1 === entry2;
239
250
 
240
251
  const getCellOrValueType = (cell) => {
241
252
  const type = getTypeOf(cell);
@@ -252,15 +263,9 @@ const setOrDelValue = (store, valueId, value) =>
252
263
 
253
264
  const defaultSorter = (sortKey1, sortKey2) => (sortKey1 < sortKey2 ? -1 : 1);
254
265
 
255
- const transformMap = (map, toBeLikeObject, setId, delId = mapSet) => {
256
- const idsToDelete = arrayFilter(
257
- mapKeys(map),
258
- (id2) => !objHas(toBeLikeObject, id2),
259
- );
260
- arrayForEach(objIds(toBeLikeObject), (id2) =>
261
- setId(map, id2, toBeLikeObject[id2]),
262
- );
263
- arrayForEach(idsToDelete, (id2) => delId(map, id2));
266
+ const mapMatch = (map, obj, set, del = mapSet) => {
267
+ objMap(obj, (value, id2) => set(map, id2, value));
268
+ mapForEach(map, (id2) => (objHas(obj, id2) ? 0 : del(map, id2)));
264
269
  return map;
265
270
  };
266
271
  const validate = (obj, validateChild, onInvalidObj) => {
@@ -275,8 +280,12 @@ const validate = (obj, validateChild, onInvalidObj) => {
275
280
  });
276
281
  return !objIsEmpty(obj);
277
282
  };
278
- const idsChanged = (changedIds, id2, added) =>
279
- mapSet(changedIds, id2, mapGet(changedIds, id2) == -added ? void 0 : added);
283
+ const idsChanged = (changedIds, id2, addedOrRemoved) =>
284
+ mapSet(
285
+ changedIds,
286
+ id2,
287
+ mapGet(changedIds, id2) == -addedOrRemoved ? void 0 : addedOrRemoved,
288
+ );
280
289
  const createStore = () => {
281
290
  let hasTablesSchema;
282
291
  let hasValuesSchema;
@@ -433,13 +442,13 @@ const createStore = () => {
433
442
  return values;
434
443
  };
435
444
  const setValidTablesSchema = (tablesSchema) =>
436
- transformMap(
445
+ mapMatch(
437
446
  tablesSchemaMap,
438
447
  tablesSchema,
439
448
  (_tablesSchema, tableId, tableSchema) => {
440
449
  const rowDefaulted = mapNew();
441
450
  const rowNonDefaulted = setNew();
442
- transformMap(
451
+ mapMatch(
443
452
  mapEnsure(tablesSchemaMap, tableId, mapNew),
444
453
  tableSchema,
445
454
  (tableSchemaMap, cellId, cellSchema) => {
@@ -459,7 +468,7 @@ const createStore = () => {
459
468
  },
460
469
  );
461
470
  const setValidValuesSchema = (valuesSchema) =>
462
- transformMap(
471
+ mapMatch(
463
472
  valuesSchemaMap,
464
473
  valuesSchema,
465
474
  (_valuesSchema, valueId, valueSchema) => {
@@ -479,14 +488,14 @@ const createStore = () => {
479
488
  const setOrDelTables = (tables) =>
480
489
  objIsEmpty(tables) ? delTables() : setTables(tables);
481
490
  const setValidTables = (tables) =>
482
- transformMap(
491
+ mapMatch(
483
492
  tablesMap,
484
493
  tables,
485
494
  (_tables, tableId, table) => setValidTable(tableId, table),
486
495
  (_tables, tableId) => delValidTable(tableId),
487
496
  );
488
497
  const setValidTable = (tableId, table) =>
489
- transformMap(
498
+ mapMatch(
490
499
  mapEnsure(tablesMap, tableId, () => {
491
500
  tableIdsChanged(tableId, 1);
492
501
  return mapNew();
@@ -496,7 +505,7 @@ const createStore = () => {
496
505
  (tableMap, rowId) => delValidRow(tableId, tableMap, rowId),
497
506
  );
498
507
  const setValidRow = (tableId, tableMap, rowId, row, forceDel) =>
499
- transformMap(
508
+ mapMatch(
500
509
  mapEnsure(tableMap, rowId, () => {
501
510
  rowIdsChanged(tableId, rowId, 1);
502
511
  return mapNew();
@@ -532,7 +541,7 @@ const createStore = () => {
532
541
  const setOrDelValues = (values) =>
533
542
  objIsEmpty(values) ? delValues() : setValues(values);
534
543
  const setValidValues = (values) =>
535
- transformMap(
544
+ mapMatch(
536
545
  valuesMap,
537
546
  values,
538
547
  (_valuesMap, valueId, value) => setValidValue(valueId, value),
@@ -600,15 +609,19 @@ const createStore = () => {
600
609
  valueIdsChanged(valueId, -1);
601
610
  mapSet(valuesMap, valueId);
602
611
  };
603
- const tableIdsChanged = (tableId, added) =>
604
- idsChanged(changedTableIds, tableId, added);
605
- const rowIdsChanged = (tableId, rowId, added) =>
606
- idsChanged(mapEnsure(changedRowIds, tableId, mapNew), rowId, added);
607
- const cellIdsChanged = (tableId, rowId, cellId, added) =>
612
+ const tableIdsChanged = (tableId, addedOrRemoved) =>
613
+ idsChanged(changedTableIds, tableId, addedOrRemoved);
614
+ const rowIdsChanged = (tableId, rowId, addedOrRemoved) =>
615
+ idsChanged(
616
+ mapEnsure(changedRowIds, tableId, mapNew),
617
+ rowId,
618
+ addedOrRemoved,
619
+ );
620
+ const cellIdsChanged = (tableId, rowId, cellId, addedOrRemoved) =>
608
621
  idsChanged(
609
622
  mapEnsure(mapEnsure(changedCellIds, tableId, mapNew), rowId, mapNew),
610
623
  cellId,
611
- added,
624
+ addedOrRemoved,
612
625
  );
613
626
  const cellChanged = (tableId, rowId, cellId, oldCell, newCell) =>
614
627
  (mapEnsure(
@@ -616,8 +629,8 @@ const createStore = () => {
616
629
  cellId,
617
630
  () => [oldCell, 0],
618
631
  )[1] = newCell);
619
- const valueIdsChanged = (valueId, added) =>
620
- idsChanged(changedValueIds, valueId, added);
632
+ const valueIdsChanged = (valueId, addedOrRemoved) =>
633
+ idsChanged(changedValueIds, valueId, addedOrRemoved);
621
634
  const valueChanged = (valueId, oldValue, newValue) =>
622
635
  (mapEnsure(changedValues, valueId, () => [oldValue, 0])[1] = newValue);
623
636
  const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
@@ -653,7 +666,7 @@ const createStore = () => {
653
666
  const callInvalidCellListeners = (mutator) =>
654
667
  !collIsEmpty(invalidCells) && !collIsEmpty(invalidCellListeners[mutator])
655
668
  ? collForEach(
656
- mutator ? mapClone(invalidCells, mapClone2) : invalidCells,
669
+ mutator ? mapClone3(invalidCells) : invalidCells,
657
670
  (rows, tableId) =>
658
671
  collForEach(rows, (cells, rowId) =>
659
672
  collForEach(cells, (invalidCell, cellId) =>
@@ -703,8 +716,8 @@ const createStore = () => {
703
716
  ? [
704
717
  mapClone(changedTableIds),
705
718
  mapClone2(changedRowIds),
706
- mapClone(changedCellIds, mapClone2),
707
- mapClone(changedCells, mapClone2),
719
+ mapClone3(changedCellIds),
720
+ mapClone3(changedCells),
708
721
  ]
709
722
  : [changedTableIds, changedRowIds, changedCellIds, changedCells];
710
723
  if (!emptyIdListeners) {
@@ -822,12 +835,48 @@ const createStore = () => {
822
835
  transaction(() => actions(...arrayMap(args, id)));
823
836
  return store;
824
837
  };
838
+ const getTransactionChanges = () => [
839
+ mapToObj(
840
+ changedCells,
841
+ (table, tableId) =>
842
+ mapGet(changedTableIds, tableId) === -1
843
+ ? null
844
+ : mapToObj(
845
+ table,
846
+ (row, rowId) =>
847
+ mapGet(mapGet(changedRowIds, tableId), rowId) === -1
848
+ ? null
849
+ : mapToObj(
850
+ row,
851
+ ([, newCell]) => newCell ?? null,
852
+ (_, changedCell) => pairIsEqual(changedCell),
853
+ ),
854
+ objIsEmpty,
855
+ ),
856
+ objIsEmpty,
857
+ ),
858
+ mapToObj(
859
+ changedValues,
860
+ ([, newValue]) => newValue ?? null,
861
+ (_, changedValue) => pairIsEqual(changedValue),
862
+ ),
863
+ ];
864
+ const getTransactionLog = () => ({
865
+ cellsTouched,
866
+ valuesTouched,
867
+ changedCells: mapToObj3(changedCells, pairClone, pairIsEqual),
868
+ invalidCells: mapToObj3(invalidCells),
869
+ changedValues: mapToObj(changedValues, pairClone, pairIsEqual),
870
+ invalidValues: mapToObj(invalidValues),
871
+ changedTableIds: mapToObj(changedTableIds),
872
+ changedRowIds: mapToObj2(changedRowIds),
873
+ changedCellIds: mapToObj3(changedCellIds),
874
+ changedValueIds: mapToObj(changedValueIds),
875
+ });
825
876
  const getContent = () => [getTables(), getValues()];
826
- const getTables = () =>
827
- mapToObj(tablesMap, (table) => mapToObj(table, mapToObj));
877
+ const getTables = () => mapToObj3(tablesMap);
828
878
  const getTableIds = () => mapKeys(tablesMap);
829
- const getTable = (tableId) =>
830
- mapToObj(mapGet(tablesMap, id(tableId)), mapToObj);
879
+ const getTable = (tableId) => mapToObj2(mapGet(tablesMap, id(tableId)));
831
880
  const getRowIds = (tableId) => mapKeys(mapGet(tablesMap, id(tableId)));
832
881
  const getSortedRowIds = (tableId, cellId, descending, offset = 0, limit) =>
833
882
  arrayMap(
@@ -966,6 +1015,23 @@ const createStore = () => {
966
1015
  ),
967
1016
  valueId,
968
1017
  );
1018
+ const setTransactionChanges = (transactionChanges) =>
1019
+ fluentTransaction(() => {
1020
+ objMap(transactionChanges[0], (table, tableId) =>
1021
+ isUndefined(table)
1022
+ ? delTable(tableId)
1023
+ : objMap(table, (row, rowId) =>
1024
+ isUndefined(row)
1025
+ ? delRow(tableId, rowId)
1026
+ : objMap(row, (cell, cellId) =>
1027
+ setOrDelCell(store, tableId, rowId, cellId, cell),
1028
+ ),
1029
+ ),
1030
+ );
1031
+ objMap(transactionChanges[1], (value, valueId) =>
1032
+ setOrDelValue(store, valueId, value),
1033
+ );
1034
+ });
969
1035
  const setTablesJson = (tablesJson) => {
970
1036
  try {
971
1037
  setOrDelTables(jsonParse(tablesJson));
@@ -1105,36 +1171,7 @@ const createStore = () => {
1105
1171
  callKeyedValuesListenersForChanges(1);
1106
1172
  }
1107
1173
  transactions = -1;
1108
- let transactionChanges =
1109
- doRollback ||
1110
- !collIsEmpty(finishTransactionListeners[0]) ||
1111
- !collIsEmpty(finishTransactionListeners[1])
1112
- ? [
1113
- mapToObj(
1114
- changedCells,
1115
- (table) =>
1116
- mapToObj(
1117
- table,
1118
- (row) =>
1119
- mapToObj(
1120
- row,
1121
- (cells) => [...cells],
1122
- ([oldCell, newCell]) => oldCell === newCell,
1123
- ),
1124
- objIsEmpty,
1125
- ),
1126
- objIsEmpty,
1127
- ),
1128
- mapToObj(invalidCells, (map) => mapToObj(map, mapToObj)),
1129
- mapToObj(
1130
- changedValues,
1131
- (values) => [...values],
1132
- ([oldValue, newValue]) => oldValue === newValue,
1133
- ),
1134
- mapToObj(invalidValues),
1135
- ]
1136
- : [{}, {}, {}, {}];
1137
- if (doRollback?.(...transactionChanges)) {
1174
+ if (doRollback?.(getTransactionChanges, getTransactionLog)) {
1138
1175
  transactions = 1;
1139
1176
  collForEach(changedCells, (table, tableId) =>
1140
1177
  collForEach(table, (row, rowId) =>
@@ -1148,14 +1185,12 @@ const createStore = () => {
1148
1185
  );
1149
1186
  transactions = -1;
1150
1187
  cellsTouched = valuesTouched = false;
1151
- transactionChanges = [{}, {}, {}, {}];
1152
1188
  }
1153
1189
  callListeners(
1154
1190
  finishTransactionListeners[0],
1155
1191
  void 0,
1156
- cellsTouched,
1157
- valuesTouched,
1158
- ...transactionChanges,
1192
+ getTransactionChanges,
1193
+ getTransactionLog,
1159
1194
  );
1160
1195
  callInvalidCellListeners(0);
1161
1196
  if (cellsTouched) {
@@ -1168,9 +1203,8 @@ const createStore = () => {
1168
1203
  callListeners(
1169
1204
  finishTransactionListeners[1],
1170
1205
  void 0,
1171
- cellsTouched,
1172
- valuesTouched,
1173
- ...transactionChanges,
1206
+ getTransactionChanges,
1207
+ getTransactionLog,
1174
1208
  );
1175
1209
  transactions = 0;
1176
1210
  arrayForEach(
@@ -1313,6 +1347,7 @@ const createStore = () => {
1313
1347
  setValues,
1314
1348
  setPartialValues,
1315
1349
  setValue,
1350
+ setTransactionChanges,
1316
1351
  setTablesJson,
1317
1352
  setValuesJson,
1318
1353
  setJson,