tinybase 7.3.5 → 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 (59) hide show
  1. package/@types/index.d.ts +1 -0
  2. package/@types/middleware/index.d.ts +1064 -0
  3. package/@types/middleware/with-schemas/index.d.ts +1355 -0
  4. package/@types/omni/index.d.ts +1 -0
  5. package/@types/omni/with-schemas/index.d.ts +1 -0
  6. package/@types/store/index.d.ts +0 -1
  7. package/@types/with-schemas/index.d.ts +1 -0
  8. package/agents.md +33 -11
  9. package/checkpoints/index.js +8 -9
  10. package/checkpoints/with-schemas/index.js +8 -9
  11. package/index.js +484 -153
  12. package/mergeable-store/index.js +371 -135
  13. package/mergeable-store/with-schemas/index.js +371 -135
  14. package/middleware/index.js +130 -0
  15. package/middleware/with-schemas/index.js +130 -0
  16. package/min/checkpoints/index.js +1 -1
  17. package/min/checkpoints/index.js.gz +0 -0
  18. package/min/checkpoints/with-schemas/index.js +1 -1
  19. package/min/checkpoints/with-schemas/index.js.gz +0 -0
  20. package/min/index.js +1 -1
  21. package/min/index.js.gz +0 -0
  22. package/min/mergeable-store/index.js +1 -1
  23. package/min/mergeable-store/index.js.gz +0 -0
  24. package/min/mergeable-store/with-schemas/index.js +1 -1
  25. package/min/mergeable-store/with-schemas/index.js.gz +0 -0
  26. package/min/middleware/index.js +1 -0
  27. package/min/middleware/index.js.gz +0 -0
  28. package/min/middleware/with-schemas/index.js +1 -0
  29. package/min/middleware/with-schemas/index.js.gz +0 -0
  30. package/min/omni/index.js +1 -1
  31. package/min/omni/index.js.gz +0 -0
  32. package/min/omni/with-schemas/index.js +1 -1
  33. package/min/omni/with-schemas/index.js.gz +0 -0
  34. package/min/queries/index.js +1 -1
  35. package/min/queries/index.js.gz +0 -0
  36. package/min/queries/with-schemas/index.js +1 -1
  37. package/min/queries/with-schemas/index.js.gz +0 -0
  38. package/min/store/index.js +1 -1
  39. package/min/store/index.js.gz +0 -0
  40. package/min/store/with-schemas/index.js +1 -1
  41. package/min/store/with-schemas/index.js.gz +0 -0
  42. package/min/ui-react-inspector/index.js +1 -1
  43. package/min/ui-react-inspector/index.js.gz +0 -0
  44. package/min/ui-react-inspector/with-schemas/index.js +1 -1
  45. package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
  46. package/min/with-schemas/index.js +1 -1
  47. package/min/with-schemas/index.js.gz +0 -0
  48. package/omni/index.js +492 -161
  49. package/omni/with-schemas/index.js +492 -161
  50. package/package.json +37 -1
  51. package/queries/index.js +1 -6
  52. package/queries/with-schemas/index.js +1 -6
  53. package/readme.md +14 -14
  54. package/releases.md +41 -41
  55. package/store/index.js +370 -134
  56. package/store/with-schemas/index.js +370 -134
  57. package/ui-react-inspector/index.js +349 -134
  58. package/ui-react-inspector/with-schemas/index.js +349 -134
  59. package/with-schemas/index.js +484 -153
package/omni/index.js CHANGED
@@ -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;
@@ -645,12 +619,18 @@ const createCheckpoints = getCreateFunction(
645
619
  collForEach(cellsDelta2, (table, tableId) =>
646
620
  collForEach(table, (row, rowId) =>
647
621
  collForEach(row, (oldNew, cellId) =>
648
- setOrDelCell(store, tableId, rowId, cellId, oldNew[oldOrNew]),
622
+ store.setOrDelCell(
623
+ tableId,
624
+ rowId,
625
+ cellId,
626
+ oldNew[oldOrNew],
627
+ true,
628
+ ),
649
629
  ),
650
630
  ),
651
631
  );
652
632
  collForEach(valuesDelta2, (oldNew, valueId) =>
653
- setOrDelValue(store, valueId, oldNew[oldOrNew]),
633
+ store.setOrDelValue(valueId, oldNew[oldOrNew], true),
654
634
  );
655
635
  });
656
636
  listening = 1;
@@ -1249,6 +1229,27 @@ const createIndexes = getCreateFunction((store) => {
1249
1229
  return objFreeze(indexes);
1250
1230
  });
1251
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
+
1252
1253
  const stampClone = ([value, hlc]) => stampNew(value, hlc);
1253
1254
  const stampCloneWithHash = ([value, hlc, hash]) => [value, hlc, hash];
1254
1255
  const stampNew = (value, hlc) => (hlc ? [value, hlc] : [value]);
@@ -1293,12 +1294,15 @@ const idsChanged = (changedIds, id2, addedOrRemoved) =>
1293
1294
  id2,
1294
1295
  mapGet(changedIds, id2) == -addedOrRemoved ? void 0 : addedOrRemoved,
1295
1296
  );
1297
+ const contentOrChangesIsEqual = ([tables1, values1], [tables2, values2]) =>
1298
+ objIsEqual(tables1, tables2) && objIsEqual(values1, values2);
1296
1299
  const createStore = () => {
1297
1300
  let hasTablesSchema;
1298
1301
  let hasValuesSchema;
1299
1302
  let hadTables = false;
1300
1303
  let hadValues = false;
1301
1304
  let transactions = 0;
1305
+ let middleware = [];
1302
1306
  let internalListeners = [];
1303
1307
  let mutating = 0;
1304
1308
  const changedTableIds = mapNew();
@@ -1346,6 +1350,19 @@ const createStore = () => {
1346
1350
  const finishTransactionListeners = pairNewMap();
1347
1351
  const [addListener, callListeners, delListenerImpl, callListenerImpl] =
1348
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
+ );
1349
1366
  const validateTablesSchema = (tableSchema) =>
1350
1367
  objValidate(tableSchema, (tableSchema2) =>
1351
1368
  objValidate(tableSchema2, validateCellOrValueSchema),
@@ -1533,82 +1550,194 @@ const createStore = () => {
1533
1550
  );
1534
1551
  const setOrDelTables = (tables) =>
1535
1552
  objIsEmpty(tables) ? delTables() : setTables(tables);
1536
- const setValidContent = ([tables, values]) => {
1537
- (objIsEmpty(tables) ? delTables : setTables)(tables);
1538
- (objIsEmpty(values) ? delValues : setValues)(values);
1539
- };
1540
- const setValidTables = (tables) =>
1541
- mapMatch(
1542
- 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(
1543
1581
  tables,
1544
- (_tables, tableId, table) => setValidTable(tableId, table),
1545
- (_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,
1546
1599
  );
1547
- const setValidTable = (tableId, table) =>
1548
- mapMatch(
1549
- mapEnsure(tablesMap, tableId, () => {
1550
- tableIdsChanged(tableId, 1);
1551
- mapSet(tablePoolFunctions, tableId, getPoolFunctions());
1552
- mapSet(tableCellIds, tableId, mapNew());
1553
- return mapNew();
1554
- }),
1600
+ const setValidTable = (tableId, table, forceDel) =>
1601
+ ifTransformed(
1555
1602
  table,
1556
- (tableMap, rowId, row) => setValidRow(tableId, tableMap, rowId, row),
1557
- (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,
1558
1627
  );
1559
1628
  const setValidRow = (tableId, tableMap, rowId, row, forceDel) =>
1560
- mapMatch(
1561
- mapEnsure(tableMap, rowId, () => {
1562
- rowIdsChanged(tableId, rowId, 1);
1563
- return mapNew();
1564
- }),
1629
+ ifTransformed(
1565
1630
  row,
1566
- (rowMap, cellId, cell) =>
1567
- setValidCell(tableId, rowId, rowMap, cellId, cell),
1568
- (rowMap, cellId) =>
1569
- delValidCell(tableId, tableMap, rowId, rowMap, cellId, forceDel),
1570
- );
1571
- const setValidCell = (tableId, rowId, rowMap, cellId, cell) => {
1572
- if (!collHas(rowMap, cellId)) {
1573
- cellIdsChanged(tableId, rowId, cellId, 1);
1574
- }
1575
- const oldCell = mapGet(rowMap, cellId);
1576
- if (cell !== oldCell) {
1577
- cellChanged(tableId, rowId, cellId, oldCell, cell);
1578
- mapSet(rowMap, cellId, cell);
1579
- }
1580
- };
1581
- 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
+ ) =>
1582
1685
  ifNotUndefined(
1583
1686
  mapGet(tableMap, rowId),
1584
- (rowMap) => setValidCell(tableId, rowId, rowMap, cellId, validCell),
1585
- () =>
1586
- setValidRow(
1587
- tableId,
1588
- tableMap,
1589
- 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(
1590
1694
  addDefaultsToRow({[cellId]: validCell}, tableId, rowId),
1591
- ),
1695
+ (cell, cellId2) =>
1696
+ setValidCell(tableId, rowId, rowMap, cellId2, cell, skipMiddleware),
1697
+ );
1698
+ },
1592
1699
  );
1593
- const setOrDelValues = (values) =>
1594
- objIsEmpty(values) ? delValues() : setValues(values);
1595
- const setValidValues = (values) =>
1596
- mapMatch(
1597
- valuesMap,
1700
+ const setValidValues = (values, forceDel) =>
1701
+ ifTransformed(
1598
1702
  values,
1599
- (_valuesMap, valueId, value) => setValidValue(valueId, value),
1600
- (_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
+ },
1601
1740
  );
1602
- const setValidValue = (valueId, value) => {
1603
- if (!collHas(valuesMap, valueId)) {
1604
- valueIdsChanged(valueId, 1);
1605
- }
1606
- const oldValue = mapGet(valuesMap, valueId);
1607
- if (value !== oldValue) {
1608
- valueChanged(valueId, oldValue, value);
1609
- mapSet(valuesMap, valueId, value);
1610
- }
1611
- };
1612
1741
  const getNewRowId = (tableId, reuse) => {
1613
1742
  const [getId] = mapGet(tablePoolFunctions, tableId);
1614
1743
  let rowId;
@@ -1618,14 +1747,34 @@ const createStore = () => {
1618
1747
  return rowId;
1619
1748
  };
1620
1749
  const getOrCreateTable = (tableId) =>
1621
- mapGet(tablesMap, tableId) ?? setValidTable(tableId, {});
1622
- 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
+ };
1623
1762
  const delValidRow = (tableId, tableMap, rowId) => {
1624
- const [, releaseId] = mapGet(tablePoolFunctions, tableId);
1625
- releaseId(rowId);
1626
- 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
+ }
1627
1768
  };
1628
- 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
+ ) => {
1629
1778
  const defaultCell = mapGet(
1630
1779
  mapGet(tablesSchemaRowCache, tableId)?.[0],
1631
1780
  cellId,
@@ -1633,34 +1782,44 @@ const createStore = () => {
1633
1782
  if (!isUndefined(defaultCell) && !forceDel) {
1634
1783
  return setValidCell(tableId, rowId, row, cellId, defaultCell);
1635
1784
  }
1636
- const delCell2 = (cellId2) => {
1637
- cellChanged(tableId, rowId, cellId2, mapGet(row, cellId2));
1638
- cellIdsChanged(tableId, rowId, cellId2, -1);
1639
- mapSet(row, cellId2);
1640
- };
1641
- if (isUndefined(defaultCell)) {
1642
- delCell2(cellId);
1643
- } else {
1644
- mapForEach(row, delCell2);
1645
- }
1646
- if (collIsEmpty(row)) {
1647
- rowIdsChanged(tableId, rowId, -1);
1648
- if (collIsEmpty(mapSet(table, rowId))) {
1649
- tableIdsChanged(tableId, -1);
1650
- mapSet(tablesMap, tableId);
1651
- mapSet(tablePoolFunctions, tableId);
1652
- 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
+ }
1653
1807
  }
1654
1808
  }
1655
1809
  };
1656
- const delValidValue = (valueId) => {
1810
+ const delValidValue = (valueId, skipMiddleware) => {
1657
1811
  const defaultValue = mapGet(valuesDefaulted, valueId);
1658
1812
  if (!isUndefined(defaultValue)) {
1659
1813
  return setValidValue(valueId, defaultValue);
1660
1814
  }
1661
- valueChanged(valueId, mapGet(valuesMap, valueId));
1662
- valueIdsChanged(valueId, -1);
1663
- 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
+ }
1664
1823
  };
1665
1824
  const tableIdsChanged = (tableId, addedOrRemoved) =>
1666
1825
  idsChanged(changedTableIds, tableId, addedOrRemoved);
@@ -2119,14 +2278,14 @@ const createStore = () => {
2119
2278
  if (validateRow(tableId2, rowId2, partialRow, 1)) {
2120
2279
  const table = getOrCreateTable(tableId2);
2121
2280
  objMap(partialRow, (cell, cellId) =>
2122
- setCellIntoDefaultRow(tableId2, table, rowId2, cellId, cell),
2281
+ setCellIntoNewRow(tableId2, table, rowId2, cellId, cell),
2123
2282
  );
2124
2283
  }
2125
2284
  },
2126
2285
  tableId,
2127
2286
  rowId,
2128
2287
  );
2129
- const setCell = (tableId, rowId, cellId, cell) =>
2288
+ const setCell = (tableId, rowId, cellId, cell, skipMiddleware) =>
2130
2289
  fluentTransaction(
2131
2290
  (tableId2, rowId2, cellId2) =>
2132
2291
  ifNotUndefined(
@@ -2137,12 +2296,13 @@ const createStore = () => {
2137
2296
  isFunction(cell) ? cell(getCell(tableId2, rowId2, cellId2)) : cell,
2138
2297
  ),
2139
2298
  (validCell) =>
2140
- setCellIntoDefaultRow(
2299
+ setCellIntoNewRow(
2141
2300
  tableId2,
2142
2301
  getOrCreateTable(tableId2),
2143
2302
  rowId2,
2144
2303
  cellId2,
2145
2304
  validCell,
2305
+ skipMiddleware,
2146
2306
  ),
2147
2307
  ),
2148
2308
  tableId,
@@ -2161,7 +2321,7 @@ const createStore = () => {
2161
2321
  )
2162
2322
  : 0,
2163
2323
  );
2164
- const setValue = (valueId, value) =>
2324
+ const setValue = (valueId, value, skipMiddleware) =>
2165
2325
  fluentTransaction(
2166
2326
  (valueId2) =>
2167
2327
  ifNotUndefined(
@@ -2169,27 +2329,40 @@ const createStore = () => {
2169
2329
  valueId2,
2170
2330
  isFunction(value) ? value(getValue(valueId2)) : value,
2171
2331
  ),
2172
- (validValue) => setValidValue(valueId2, validValue),
2332
+ (validValue) => setValidValue(valueId2, validValue, skipMiddleware),
2173
2333
  ),
2174
2334
  valueId,
2175
2335
  );
2176
2336
  const applyChanges = (changes) =>
2177
- fluentTransaction(() => {
2178
- objMap(changes[0], (table, tableId) =>
2179
- isUndefined(table)
2180
- ? delTable(tableId)
2181
- : objMap(table, (row, rowId) =>
2182
- isUndefined(row)
2183
- ? delRow(tableId, rowId)
2184
- : objMap(row, (cell, cellId) =>
2185
- setOrDelCell(store, tableId, rowId, cellId, cell),
2186
- ),
2187
- ),
2188
- );
2189
- objMap(changes[1], (value, valueId) =>
2190
- setOrDelValue(store, valueId, value),
2191
- );
2192
- });
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
+ );
2193
2366
  const setTablesJson = (tablesJson) => {
2194
2367
  tryCatch(() => setOrDelTables(jsonParse(tablesJson)));
2195
2368
  return store;
@@ -2236,7 +2409,12 @@ const createStore = () => {
2236
2409
  setTablesSchema(tablesSchema);
2237
2410
  setValuesSchema(valuesSchema);
2238
2411
  });
2239
- const delTables = () => fluentTransaction(() => setValidTables({}));
2412
+ const delTables = () =>
2413
+ fluentTransaction(() =>
2414
+ (whileMutating(() => middleware[7]?.()) ?? true)
2415
+ ? setValidTables({}, true)
2416
+ : 0,
2417
+ );
2240
2418
  const delTable = (tableId) =>
2241
2419
  fluentTransaction(
2242
2420
  (tableId2) =>
@@ -2254,7 +2432,7 @@ const createStore = () => {
2254
2432
  tableId,
2255
2433
  rowId,
2256
2434
  );
2257
- const delCell = (tableId, rowId, cellId, forceDel) =>
2435
+ const delCell = (tableId, rowId, cellId, forceDel, skipMiddleware) =>
2258
2436
  fluentTransaction(
2259
2437
  (tableId2, rowId2, cellId2) =>
2260
2438
  ifNotUndefined(mapGet(tablesMap, tableId2), (tableMap) =>
@@ -2267,6 +2445,7 @@ const createStore = () => {
2267
2445
  rowMap,
2268
2446
  cellId2,
2269
2447
  forceDel,
2448
+ skipMiddleware,
2270
2449
  )
2271
2450
  : 0,
2272
2451
  ),
@@ -2275,11 +2454,18 @@ const createStore = () => {
2275
2454
  rowId,
2276
2455
  cellId,
2277
2456
  );
2278
- const delValues = () => fluentTransaction(() => setValidValues({}));
2279
- const delValue = (valueId) =>
2457
+ const delValues = () =>
2458
+ fluentTransaction(() =>
2459
+ (whileMutating(() => middleware[11]?.()) ?? true)
2460
+ ? setValidValues({}, true)
2461
+ : 0,
2462
+ );
2463
+ const delValue = (valueId, skipMiddleware) =>
2280
2464
  fluentTransaction(
2281
2465
  (valueId2) =>
2282
- collHas(valuesMap, valueId2) ? delValidValue(valueId2) : 0,
2466
+ collHas(valuesMap, valueId2)
2467
+ ? delValidValue(valueId2, skipMiddleware)
2468
+ : 0,
2283
2469
  valueId,
2284
2470
  );
2285
2471
  const delTablesSchema = () =>
@@ -2361,27 +2547,27 @@ const createStore = () => {
2361
2547
  transactions--;
2362
2548
  if (transactions == 0) {
2363
2549
  transactions = 1;
2364
- mutating = 1;
2365
- callInvalidCellListeners(1);
2366
- if (!collIsEmpty(changedCells)) {
2367
- callTabularListenersForChanges(1);
2368
- }
2369
- callInvalidValueListeners(1);
2370
- if (!collIsEmpty(changedValues)) {
2371
- callValuesListenersForChanges(1);
2372
- }
2373
- mutating = 0;
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
+ });
2374
2560
  if (doRollback?.(store)) {
2375
2561
  collForEach(changedCells, (table, tableId) =>
2376
2562
  collForEach(table, (row, rowId) =>
2377
2563
  collForEach(row, ([oldCell], cellId) =>
2378
- setOrDelCell(store, tableId, rowId, cellId, oldCell),
2564
+ setOrDelCell(tableId, rowId, cellId, oldCell, true),
2379
2565
  ),
2380
2566
  ),
2381
2567
  );
2382
2568
  collClear(changedCells);
2383
2569
  collForEach(changedValues, ([oldValue], valueId) =>
2384
- setOrDelValue(store, valueId, oldValue),
2570
+ setOrDelValue(valueId, oldValue, true),
2385
2571
  );
2386
2572
  collClear(changedValues);
2387
2573
  }
@@ -2508,6 +2694,38 @@ const createStore = () => {
2508
2694
  collSize2(startTransactionListeners) +
2509
2695
  pairCollSize2(finishTransactionListeners),
2510
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
+ ]);
2511
2729
  const setInternalListeners = (
2512
2730
  preStartTransaction,
2513
2731
  preFinishTransaction,
@@ -2601,6 +2819,9 @@ const createStore = () => {
2601
2819
  addListener,
2602
2820
  callListeners,
2603
2821
  setInternalListeners,
2822
+ setMiddleware,
2823
+ setOrDelCell,
2824
+ setOrDelValue,
2604
2825
  };
2605
2826
  objMap(
2606
2827
  {
@@ -3157,7 +3378,8 @@ const createMergeableStore = (uniqueId, getNow) => {
3157
3378
  strStartsWith(name, DEL) ||
3158
3379
  strStartsWith(name, 'apply') ||
3159
3380
  strEndsWith(name, TRANSACTION) ||
3160
- name == 'call' + LISTENER
3381
+ name == 'call' + LISTENER ||
3382
+ name == 'use'
3161
3383
  ? (...args) => {
3162
3384
  method(...args);
3163
3385
  return mergeableStore;
@@ -3350,6 +3572,115 @@ const createMetrics = getCreateFunction((store) => {
3350
3572
  return objFreeze(metrics);
3351
3573
  });
3352
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
+
3353
3684
  const Status = {
3354
3685
  Idle: 0 /* Idle */,
3355
3686
  Loading: 1 /* Loading */,
@@ -6185,8 +6516,7 @@ const createQueries = getCreateFunction((store) => {
6185
6516
  selectJoinWhereStore.transaction(() =>
6186
6517
  arrayEvery(wheres, (where2) => where2(getTableCell))
6187
6518
  ? mapForEach(selects, (asCellId, tableCellGetter) =>
6188
- setOrDelCell(
6189
- selectJoinWhereStore,
6519
+ selectJoinWhereStore.setOrDelCell(
6190
6520
  queryId,
6191
6521
  rootRowId,
6192
6522
  asCellId,
@@ -11694,6 +12024,7 @@ export {
11694
12024
  createLocalSynchronizer,
11695
12025
  createMergeableStore,
11696
12026
  createMetrics,
12027
+ createMiddleware,
11697
12028
  createOpfsPersister,
11698
12029
  createPartyKitPersister,
11699
12030
  createPglitePersister,