@tanstack/db-sqlite-persistence-core 0.1.11 → 0.2.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.
@@ -73,6 +73,21 @@ export type SQLitePullSinceResult<TKey extends string | number> =
73
73
 
74
74
  const DEFAULT_SCHEMA_VERSION = 1
75
75
  const DEFAULT_PULL_SINCE_RELOAD_THRESHOLD = 128
76
+
77
+ /**
78
+ * Default cap on retained `applied_tx` rows per collection. The log is a
79
+ * replayable cache, so a bounded row count keeps SQLite files from growing
80
+ * without limit. Pass `appliedTxPruneMaxRows: 0` to disable the row cap.
81
+ */
82
+ export const DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS = 1_000
83
+
84
+ /**
85
+ * Default age backstop for retained `applied_tx` rows, in seconds (24h). Rows
86
+ * older than this are pruned on the next write. Pass
87
+ * `appliedTxPruneMaxAgeSeconds: 0` to disable the age backstop.
88
+ */
89
+ export const DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS = 24 * 60 * 60
90
+
76
91
  const SQLITE_MAX_IN_BATCH_SIZE = 900
77
92
  const SAFE_IDENTIFIER_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/
78
93
  const FORBIDDEN_SQL_FRAGMENT_PATTERN = /(;|--|\/\*)/
@@ -1540,42 +1555,64 @@ export class SQLiteCorePersistenceAdapter implements PersistenceAdapter {
1540
1555
  const collectionTableSql = quoteIdentifier(tableMapping.tableName)
1541
1556
  const tombstoneTableSql = quoteIdentifier(tableMapping.tombstoneTableName)
1542
1557
 
1543
- const [changedRows, deletedRows, latestVersionRows, replayRows] =
1544
- await Promise.all([
1545
- this.driver.query<{ key: string }>(
1546
- `SELECT key
1558
+ const [
1559
+ changedRows,
1560
+ deletedRows,
1561
+ latestVersionRows,
1562
+ replayRows,
1563
+ replayAvailabilityRows,
1564
+ ] = await Promise.all([
1565
+ this.driver.query<{ key: string }>(
1566
+ `SELECT key
1547
1567
  FROM ${collectionTableSql}
1548
1568
  WHERE row_version > ?`,
1549
- [fromRowVersion],
1550
- ),
1551
- this.driver.query<{ key: string }>(
1552
- `SELECT key
1569
+ [fromRowVersion],
1570
+ ),
1571
+ this.driver.query<{ key: string }>(
1572
+ `SELECT key
1553
1573
  FROM ${tombstoneTableSql}
1554
1574
  WHERE row_version > ?`,
1555
- [fromRowVersion],
1556
- ),
1557
- this.driver.query<{ latest_row_version: number }>(
1558
- `SELECT latest_row_version
1575
+ [fromRowVersion],
1576
+ ),
1577
+ this.driver.query<{ latest_row_version: number }>(
1578
+ `SELECT latest_row_version
1559
1579
  FROM collection_version
1560
1580
  WHERE collection_id = ?
1561
1581
  LIMIT 1`,
1562
- [collectionId],
1563
- ),
1564
- this.driver.query<{
1565
- tx_id: string
1566
- row_version: number
1567
- replay_json: string | null
1568
- replay_requires_full_reload: number
1569
- }>(
1570
- `SELECT tx_id, row_version, replay_json, replay_requires_full_reload
1582
+ [collectionId],
1583
+ ),
1584
+ this.driver.query<{
1585
+ tx_id: string
1586
+ row_version: number
1587
+ replay_json: string | null
1588
+ replay_requires_full_reload: number
1589
+ }>(
1590
+ `SELECT tx_id, row_version, replay_json, replay_requires_full_reload
1571
1591
  FROM applied_tx
1572
1592
  WHERE collection_id = ? AND row_version > ?
1573
1593
  ORDER BY term ASC, seq ASC`,
1574
- [collectionId, fromRowVersion],
1575
- ),
1576
- ])
1594
+ [collectionId, fromRowVersion],
1595
+ ),
1596
+ this.driver.query<{ min_row_version: number | null }>(
1597
+ `SELECT MIN(row_version) AS min_row_version
1598
+ FROM applied_tx
1599
+ WHERE collection_id = ?`,
1600
+ [collectionId],
1601
+ ),
1602
+ ])
1577
1603
 
1578
1604
  const latestRowVersion = latestVersionRows[0]?.latest_row_version ?? 0
1605
+ const replayFloor = replayAvailabilityRows[0]?.min_row_version
1606
+ if (
1607
+ latestRowVersion > fromRowVersion &&
1608
+ (replayFloor == null || replayFloor > fromRowVersion + 1)
1609
+ ) {
1610
+ return {
1611
+ latestRowVersion,
1612
+ requiresFullReload: true,
1613
+ }
1614
+ }
1615
+
1579
1616
  const changedKeyCount = changedRows.length + deletedRows.length
1580
1617
 
1581
1618
  if (changedKeyCount > this.pullSinceReloadThreshold) {