@tanstack/node-db-sqlite-persistence 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.
package/README.md CHANGED
@@ -47,3 +47,32 @@ export const todosCollection = createCollection(
47
47
  mode-specific behavior (`sync-present` vs `sync-absent`) automatically.
48
48
  - `schemaVersion` is specified per collection via `persistedCollectionOptions`.
49
49
  - Call `database.close()` when your app shuts down.
50
+
51
+ ## Applied transaction pruning
52
+
53
+ The `applied_tx` log is a replayable cache, so it is pruned by default to keep
54
+ the SQLite file from growing without bound. When you don't pass prune options,
55
+ the node driver applies:
56
+
57
+ - `appliedTxPruneMaxRows: 1_000` (per-collection row cap)
58
+ - `appliedTxPruneMaxAgeSeconds: 86_400` (24h age backstop)
59
+
60
+ Pruning runs inside each write transaction, so every collection self-trims on
61
+ its next sync. If a process asks to recover from a point older than the retained
62
+ replay window, recovery falls back to a full reload. Override either value to
63
+ tune retention, or pass `0` to disable that limit:
64
+
65
+ ```ts
66
+ const persistence = createNodeSQLitePersistence({
67
+ database,
68
+ appliedTxPruneMaxRows: 5_000, // higher row cap
69
+ appliedTxPruneMaxAgeSeconds: 0, // disable the age backstop
70
+ })
71
+ ```
72
+
73
+ Pruning removes rows from `applied_tx`, but SQLite may not immediately shrink
74
+ the database file on disk. Use `VACUUM`, `auto_vacuum`, or your own maintenance
75
+ process if you need to reclaim disk space.
76
+
77
+ The defaults are exported as `DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS` and
78
+ `DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS`.
@@ -2,6 +2,8 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const nodePersistence = require("./node-persistence.cjs");
4
4
  const dbSqlitePersistenceCore = require("@tanstack/db-sqlite-persistence-core");
5
+ exports.DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS = nodePersistence.DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS;
6
+ exports.DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS = nodePersistence.DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS;
5
7
  exports.createNodeSQLitePersistence = nodePersistence.createNodeSQLitePersistence;
6
8
  Object.defineProperty(exports, "persistedCollectionOptions", {
7
9
  enumerable: true,
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
@@ -1,4 +1,4 @@
1
- export { createNodeSQLitePersistence } from './node-persistence.cjs';
1
+ export { createNodeSQLitePersistence, DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS, DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS, } from './node-persistence.cjs';
2
2
  export type { BetterSqlite3Database, NodeSQLitePersistenceOptions, NodeSQLiteSchemaMismatchPolicy, } from './node-persistence.cjs';
3
3
  export { persistedCollectionOptions } from '@tanstack/db-sqlite-persistence-core';
4
4
  export type { PersistedCollectionCoordinator, PersistedCollectionPersistence, } from '@tanstack/db-sqlite-persistence-core';
@@ -2,6 +2,8 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const dbSqlitePersistenceCore = require("@tanstack/db-sqlite-persistence-core");
4
4
  const nodeDriver = require("./node-driver.cjs");
5
+ const DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS = dbSqlitePersistenceCore.DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS;
6
+ const DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS = dbSqlitePersistenceCore.DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS;
5
7
  function normalizeSchemaMismatchPolicy(policy) {
6
8
  if (policy === `throw`) {
7
9
  return `sync-absent-error`;
@@ -26,8 +28,8 @@ function createInternalSQLiteDriver(options) {
26
28
  }
27
29
  function resolveAdapterBaseOptions(options) {
28
30
  return {
29
- appliedTxPruneMaxRows: options.appliedTxPruneMaxRows,
30
- appliedTxPruneMaxAgeSeconds: options.appliedTxPruneMaxAgeSeconds,
31
+ appliedTxPruneMaxRows: options.appliedTxPruneMaxRows ?? dbSqlitePersistenceCore.DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS,
32
+ appliedTxPruneMaxAgeSeconds: options.appliedTxPruneMaxAgeSeconds ?? dbSqlitePersistenceCore.DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS,
31
33
  pullSinceReloadThreshold: options.pullSinceReloadThreshold
32
34
  };
33
35
  }
@@ -74,5 +76,7 @@ function createNodeSQLitePersistence(options) {
74
76
  resolvePersistenceForMode: (mode) => createCollectionPersistence(mode, void 0)
75
77
  };
76
78
  }
79
+ exports.DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS = DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS;
80
+ exports.DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS = DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS;
77
81
  exports.createNodeSQLitePersistence = createNodeSQLitePersistence;
78
82
  //# sourceMappingURL=node-persistence.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"node-persistence.cjs","sources":["../../src/node-persistence.ts"],"sourcesContent":["import {\n SingleProcessCoordinator,\n createSQLiteCorePersistenceAdapter,\n} from '@tanstack/db-sqlite-persistence-core'\nimport { BetterSqlite3SQLiteDriver } from './node-driver'\nimport type {\n PersistedCollectionCoordinator,\n PersistedCollectionMode,\n PersistedCollectionPersistence,\n SQLiteCoreAdapterOptions,\n SQLiteDriver,\n} from '@tanstack/db-sqlite-persistence-core'\nimport type { BetterSqlite3Database } from './node-driver'\n\nexport type { BetterSqlite3Database } from './node-driver'\n\ntype NodeSQLiteCoreSchemaMismatchPolicy =\n | `sync-present-reset`\n | `sync-absent-error`\n | `reset`\n\nexport type NodeSQLiteSchemaMismatchPolicy =\n | NodeSQLiteCoreSchemaMismatchPolicy\n | `throw`\n\ntype NodeSQLitePersistenceBaseOptions = Omit<\n SQLiteCoreAdapterOptions,\n `driver` | `schemaVersion` | `schemaMismatchPolicy`\n> & {\n database: BetterSqlite3Database\n pragmas?: ReadonlyArray<string>\n coordinator?: PersistedCollectionCoordinator\n schemaMismatchPolicy?: NodeSQLiteSchemaMismatchPolicy\n}\n\nexport type NodeSQLitePersistenceOptions = NodeSQLitePersistenceBaseOptions\n\nfunction normalizeSchemaMismatchPolicy(\n policy: NodeSQLiteSchemaMismatchPolicy,\n): NodeSQLiteCoreSchemaMismatchPolicy {\n if (policy === `throw`) {\n return `sync-absent-error`\n }\n\n return policy\n}\n\nfunction resolveSchemaMismatchPolicy(\n explicitPolicy: NodeSQLiteSchemaMismatchPolicy | undefined,\n mode: PersistedCollectionMode,\n): NodeSQLiteCoreSchemaMismatchPolicy {\n if (explicitPolicy) {\n return normalizeSchemaMismatchPolicy(explicitPolicy)\n }\n\n return mode === `sync-present` ? `sync-present-reset` : `sync-absent-error`\n}\n\nfunction createAdapterCacheKey(\n schemaMismatchPolicy: NodeSQLiteCoreSchemaMismatchPolicy,\n schemaVersion: number | undefined,\n): string {\n const schemaVersionKey =\n schemaVersion === undefined ? `schema:default` : `schema:${schemaVersion}`\n return `${schemaMismatchPolicy}|${schemaVersionKey}`\n}\n\nfunction createInternalSQLiteDriver(\n options: NodeSQLitePersistenceOptions,\n): SQLiteDriver {\n return new BetterSqlite3SQLiteDriver({\n database: options.database,\n ...(options.pragmas ? { pragmas: options.pragmas } : {}),\n })\n}\n\nfunction resolveAdapterBaseOptions(\n options: NodeSQLitePersistenceOptions,\n): Omit<\n SQLiteCoreAdapterOptions,\n `driver` | `schemaVersion` | `schemaMismatchPolicy`\n> {\n return {\n appliedTxPruneMaxRows: options.appliedTxPruneMaxRows,\n appliedTxPruneMaxAgeSeconds: options.appliedTxPruneMaxAgeSeconds,\n pullSinceReloadThreshold: options.pullSinceReloadThreshold,\n }\n}\n\n/**\n * Creates a shared SQLite persistence instance that can be reused by many\n * collections on the same database. Collection-specific schema versions are\n * resolved by `persistedCollectionOptions` via `resolvePersistenceForCollection`.\n */\nexport function createNodeSQLitePersistence(\n options: NodeSQLitePersistenceOptions,\n): PersistedCollectionPersistence {\n const { coordinator, schemaMismatchPolicy } = options\n const driver = createInternalSQLiteDriver(options)\n const adapterBaseOptions = resolveAdapterBaseOptions(options)\n const resolvedCoordinator = coordinator ?? new SingleProcessCoordinator()\n const adapterCache = new Map<\n string,\n ReturnType<typeof createSQLiteCorePersistenceAdapter>\n >()\n\n const getAdapterForCollection = (\n mode: PersistedCollectionMode,\n schemaVersion: number | undefined,\n ) => {\n const resolvedSchemaMismatchPolicy = resolveSchemaMismatchPolicy(\n schemaMismatchPolicy,\n mode,\n )\n const cacheKey = createAdapterCacheKey(\n resolvedSchemaMismatchPolicy,\n schemaVersion,\n )\n const cachedAdapter = adapterCache.get(cacheKey)\n if (cachedAdapter) {\n return cachedAdapter\n }\n\n const adapter = createSQLiteCorePersistenceAdapter({\n ...adapterBaseOptions,\n driver,\n schemaMismatchPolicy: resolvedSchemaMismatchPolicy,\n ...(schemaVersion === undefined ? {} : { schemaVersion }),\n })\n adapterCache.set(cacheKey, adapter)\n return adapter\n }\n\n const createCollectionPersistence = (\n mode: PersistedCollectionMode,\n schemaVersion: number | undefined,\n ): PersistedCollectionPersistence => ({\n adapter: getAdapterForCollection(mode, schemaVersion),\n coordinator: resolvedCoordinator,\n })\n\n const defaultPersistence = createCollectionPersistence(\n `sync-absent`,\n undefined,\n )\n\n return {\n ...defaultPersistence,\n resolvePersistenceForCollection: ({ mode, schemaVersion }) =>\n createCollectionPersistence(mode, schemaVersion),\n // Backward compatible fallback for older callers.\n resolvePersistenceForMode: (mode) =>\n createCollectionPersistence(mode, undefined),\n }\n}\n"],"names":["BetterSqlite3SQLiteDriver","SingleProcessCoordinator","createSQLiteCorePersistenceAdapter"],"mappings":";;;;AAqCA,SAAS,8BACP,QACoC;AACpC,MAAI,WAAW,SAAS;AACtB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,4BACP,gBACA,MACoC;AACpC,MAAI,gBAAgB;AAClB,WAAO,8BAA8B,cAAc;AAAA,EACrD;AAEA,SAAO,SAAS,iBAAiB,uBAAuB;AAC1D;AAEA,SAAS,sBACP,sBACA,eACQ;AACR,QAAM,mBACJ,kBAAkB,SAAY,mBAAmB,UAAU,aAAa;AAC1E,SAAO,GAAG,oBAAoB,IAAI,gBAAgB;AACpD;AAEA,SAAS,2BACP,SACc;AACd,SAAO,IAAIA,WAAAA,0BAA0B;AAAA,IACnC,UAAU,QAAQ;AAAA,IAClB,GAAI,QAAQ,UAAU,EAAE,SAAS,QAAQ,QAAA,IAAY,CAAA;AAAA,EAAC,CACvD;AACH;AAEA,SAAS,0BACP,SAIA;AACA,SAAO;AAAA,IACL,uBAAuB,QAAQ;AAAA,IAC/B,6BAA6B,QAAQ;AAAA,IACrC,0BAA0B,QAAQ;AAAA,EAAA;AAEtC;AAOO,SAAS,4BACd,SACgC;AAChC,QAAM,EAAE,aAAa,qBAAA,IAAyB;AAC9C,QAAM,SAAS,2BAA2B,OAAO;AACjD,QAAM,qBAAqB,0BAA0B,OAAO;AAC5D,QAAM,sBAAsB,eAAe,IAAIC,iDAAA;AAC/C,QAAM,mCAAmB,IAAA;AAKzB,QAAM,0BAA0B,CAC9B,MACA,kBACG;AACH,UAAM,+BAA+B;AAAA,MACnC;AAAA,MACA;AAAA,IAAA;AAEF,UAAM,WAAW;AAAA,MACf;AAAA,MACA;AAAA,IAAA;AAEF,UAAM,gBAAgB,aAAa,IAAI,QAAQ;AAC/C,QAAI,eAAe;AACjB,aAAO;AAAA,IACT;AAEA,UAAM,UAAUC,wBAAAA,mCAAmC;AAAA,MACjD,GAAG;AAAA,MACH;AAAA,MACA,sBAAsB;AAAA,MACtB,GAAI,kBAAkB,SAAY,CAAA,IAAK,EAAE,cAAA;AAAA,IAAc,CACxD;AACD,iBAAa,IAAI,UAAU,OAAO;AAClC,WAAO;AAAA,EACT;AAEA,QAAM,8BAA8B,CAClC,MACA,mBACoC;AAAA,IACpC,SAAS,wBAAwB,MAAM,aAAa;AAAA,IACpD,aAAa;AAAA,EAAA;AAGf,QAAM,qBAAqB;AAAA,IACzB;AAAA,IACA;AAAA,EAAA;AAGF,SAAO;AAAA,IACL,GAAG;AAAA,IACH,iCAAiC,CAAC,EAAE,MAAM,oBACxC,4BAA4B,MAAM,aAAa;AAAA;AAAA,IAEjD,2BAA2B,CAAC,SAC1B,4BAA4B,MAAM,MAAS;AAAA,EAAA;AAEjD;;"}
1
+ {"version":3,"file":"node-persistence.cjs","sources":["../../src/node-persistence.ts"],"sourcesContent":["import {\n DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS as CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS,\n DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS as CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS,\n SingleProcessCoordinator,\n createSQLiteCorePersistenceAdapter,\n} from '@tanstack/db-sqlite-persistence-core'\nimport { BetterSqlite3SQLiteDriver } from './node-driver'\nimport type {\n PersistedCollectionCoordinator,\n PersistedCollectionMode,\n PersistedCollectionPersistence,\n SQLiteCoreAdapterOptions,\n SQLiteDriver,\n} from '@tanstack/db-sqlite-persistence-core'\nimport type { BetterSqlite3Database } from './node-driver'\n\nexport type { BetterSqlite3Database } from './node-driver'\n\ntype NodeSQLiteCoreSchemaMismatchPolicy =\n | `sync-present-reset`\n | `sync-absent-error`\n | `reset`\n\nexport type NodeSQLiteSchemaMismatchPolicy =\n | NodeSQLiteCoreSchemaMismatchPolicy\n | `throw`\n\ntype NodeSQLitePersistenceBaseOptions = Omit<\n SQLiteCoreAdapterOptions,\n `driver` | `schemaVersion` | `schemaMismatchPolicy`\n> & {\n database: BetterSqlite3Database\n pragmas?: ReadonlyArray<string>\n coordinator?: PersistedCollectionCoordinator\n schemaMismatchPolicy?: NodeSQLiteSchemaMismatchPolicy\n}\n\nexport type NodeSQLitePersistenceOptions = NodeSQLitePersistenceBaseOptions\n\n/**\n * Default cap on retained `applied_tx` rows per collection. The log is a\n * replayable cache, so a bounded row count keeps SQLite files from growing\n * without limit. Pass `appliedTxPruneMaxRows: 0` to disable the row cap.\n */\nexport const DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS =\n CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS\n\n/**\n * Default age backstop for retained `applied_tx` rows, in seconds (24h). Rows\n * older than this are pruned on the next write. Pass\n * `appliedTxPruneMaxAgeSeconds: 0` to disable the age backstop.\n */\nexport const DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS =\n CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS\n\nfunction normalizeSchemaMismatchPolicy(\n policy: NodeSQLiteSchemaMismatchPolicy,\n): NodeSQLiteCoreSchemaMismatchPolicy {\n if (policy === `throw`) {\n return `sync-absent-error`\n }\n\n return policy\n}\n\nfunction resolveSchemaMismatchPolicy(\n explicitPolicy: NodeSQLiteSchemaMismatchPolicy | undefined,\n mode: PersistedCollectionMode,\n): NodeSQLiteCoreSchemaMismatchPolicy {\n if (explicitPolicy) {\n return normalizeSchemaMismatchPolicy(explicitPolicy)\n }\n\n return mode === `sync-present` ? `sync-present-reset` : `sync-absent-error`\n}\n\nfunction createAdapterCacheKey(\n schemaMismatchPolicy: NodeSQLiteCoreSchemaMismatchPolicy,\n schemaVersion: number | undefined,\n): string {\n const schemaVersionKey =\n schemaVersion === undefined ? `schema:default` : `schema:${schemaVersion}`\n return `${schemaMismatchPolicy}|${schemaVersionKey}`\n}\n\nfunction createInternalSQLiteDriver(\n options: NodeSQLitePersistenceOptions,\n): SQLiteDriver {\n return new BetterSqlite3SQLiteDriver({\n database: options.database,\n ...(options.pragmas ? { pragmas: options.pragmas } : {}),\n })\n}\n\nfunction resolveAdapterBaseOptions(\n options: NodeSQLitePersistenceOptions,\n): Omit<\n SQLiteCoreAdapterOptions,\n `driver` | `schemaVersion` | `schemaMismatchPolicy`\n> {\n return {\n appliedTxPruneMaxRows:\n options.appliedTxPruneMaxRows ?? CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS,\n appliedTxPruneMaxAgeSeconds:\n options.appliedTxPruneMaxAgeSeconds ??\n CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS,\n pullSinceReloadThreshold: options.pullSinceReloadThreshold,\n }\n}\n\n/**\n * Creates a shared SQLite persistence instance that can be reused by many\n * collections on the same database. Collection-specific schema versions are\n * resolved by `persistedCollectionOptions` via `resolvePersistenceForCollection`.\n */\nexport function createNodeSQLitePersistence(\n options: NodeSQLitePersistenceOptions,\n): PersistedCollectionPersistence {\n const { coordinator, schemaMismatchPolicy } = options\n const driver = createInternalSQLiteDriver(options)\n const adapterBaseOptions = resolveAdapterBaseOptions(options)\n const resolvedCoordinator = coordinator ?? new SingleProcessCoordinator()\n const adapterCache = new Map<\n string,\n ReturnType<typeof createSQLiteCorePersistenceAdapter>\n >()\n\n const getAdapterForCollection = (\n mode: PersistedCollectionMode,\n schemaVersion: number | undefined,\n ) => {\n const resolvedSchemaMismatchPolicy = resolveSchemaMismatchPolicy(\n schemaMismatchPolicy,\n mode,\n )\n const cacheKey = createAdapterCacheKey(\n resolvedSchemaMismatchPolicy,\n schemaVersion,\n )\n const cachedAdapter = adapterCache.get(cacheKey)\n if (cachedAdapter) {\n return cachedAdapter\n }\n\n const adapter = createSQLiteCorePersistenceAdapter({\n ...adapterBaseOptions,\n driver,\n schemaMismatchPolicy: resolvedSchemaMismatchPolicy,\n ...(schemaVersion === undefined ? {} : { schemaVersion }),\n })\n adapterCache.set(cacheKey, adapter)\n return adapter\n }\n\n const createCollectionPersistence = (\n mode: PersistedCollectionMode,\n schemaVersion: number | undefined,\n ): PersistedCollectionPersistence => ({\n adapter: getAdapterForCollection(mode, schemaVersion),\n coordinator: resolvedCoordinator,\n })\n\n const defaultPersistence = createCollectionPersistence(\n `sync-absent`,\n undefined,\n )\n\n return {\n ...defaultPersistence,\n resolvePersistenceForCollection: ({ mode, schemaVersion }) =>\n createCollectionPersistence(mode, schemaVersion),\n // Backward compatible fallback for older callers.\n resolvePersistenceForMode: (mode) =>\n createCollectionPersistence(mode, undefined),\n }\n}\n"],"names":["CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS","CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS","BetterSqlite3SQLiteDriver","SingleProcessCoordinator","createSQLiteCorePersistenceAdapter"],"mappings":";;;;AA4CO,MAAM,oCACXA,wBAAAA;AAOK,MAAM,2CACXC,wBAAAA;AAEF,SAAS,8BACP,QACoC;AACpC,MAAI,WAAW,SAAS;AACtB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,4BACP,gBACA,MACoC;AACpC,MAAI,gBAAgB;AAClB,WAAO,8BAA8B,cAAc;AAAA,EACrD;AAEA,SAAO,SAAS,iBAAiB,uBAAuB;AAC1D;AAEA,SAAS,sBACP,sBACA,eACQ;AACR,QAAM,mBACJ,kBAAkB,SAAY,mBAAmB,UAAU,aAAa;AAC1E,SAAO,GAAG,oBAAoB,IAAI,gBAAgB;AACpD;AAEA,SAAS,2BACP,SACc;AACd,SAAO,IAAIC,WAAAA,0BAA0B;AAAA,IACnC,UAAU,QAAQ;AAAA,IAClB,GAAI,QAAQ,UAAU,EAAE,SAAS,QAAQ,QAAA,IAAY,CAAA;AAAA,EAAC,CACvD;AACH;AAEA,SAAS,0BACP,SAIA;AACA,SAAO;AAAA,IACL,uBACE,QAAQ,yBAAyBF,wBAAAA;AAAAA,IACnC,6BACE,QAAQ,+BACRC,wBAAAA;AAAAA,IACF,0BAA0B,QAAQ;AAAA,EAAA;AAEtC;AAOO,SAAS,4BACd,SACgC;AAChC,QAAM,EAAE,aAAa,qBAAA,IAAyB;AAC9C,QAAM,SAAS,2BAA2B,OAAO;AACjD,QAAM,qBAAqB,0BAA0B,OAAO;AAC5D,QAAM,sBAAsB,eAAe,IAAIE,iDAAA;AAC/C,QAAM,mCAAmB,IAAA;AAKzB,QAAM,0BAA0B,CAC9B,MACA,kBACG;AACH,UAAM,+BAA+B;AAAA,MACnC;AAAA,MACA;AAAA,IAAA;AAEF,UAAM,WAAW;AAAA,MACf;AAAA,MACA;AAAA,IAAA;AAEF,UAAM,gBAAgB,aAAa,IAAI,QAAQ;AAC/C,QAAI,eAAe;AACjB,aAAO;AAAA,IACT;AAEA,UAAM,UAAUC,wBAAAA,mCAAmC;AAAA,MACjD,GAAG;AAAA,MACH;AAAA,MACA,sBAAsB;AAAA,MACtB,GAAI,kBAAkB,SAAY,CAAA,IAAK,EAAE,cAAA;AAAA,IAAc,CACxD;AACD,iBAAa,IAAI,UAAU,OAAO;AAClC,WAAO;AAAA,EACT;AAEA,QAAM,8BAA8B,CAClC,MACA,mBACoC;AAAA,IACpC,SAAS,wBAAwB,MAAM,aAAa;AAAA,IACpD,aAAa;AAAA,EAAA;AAGf,QAAM,qBAAqB;AAAA,IACzB;AAAA,IACA;AAAA,EAAA;AAGF,SAAO;AAAA,IACL,GAAG;AAAA,IACH,iCAAiC,CAAC,EAAE,MAAM,oBACxC,4BAA4B,MAAM,aAAa;AAAA;AAAA,IAEjD,2BAA2B,CAAC,SAC1B,4BAA4B,MAAM,MAAS;AAAA,EAAA;AAEjD;;;;"}
@@ -10,6 +10,18 @@ type NodeSQLitePersistenceBaseOptions = Omit<SQLiteCoreAdapterOptions, `driver`
10
10
  schemaMismatchPolicy?: NodeSQLiteSchemaMismatchPolicy;
11
11
  };
12
12
  export type NodeSQLitePersistenceOptions = NodeSQLitePersistenceBaseOptions;
13
+ /**
14
+ * Default cap on retained `applied_tx` rows per collection. The log is a
15
+ * replayable cache, so a bounded row count keeps SQLite files from growing
16
+ * without limit. Pass `appliedTxPruneMaxRows: 0` to disable the row cap.
17
+ */
18
+ export declare const DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS = 1000;
19
+ /**
20
+ * Default age backstop for retained `applied_tx` rows, in seconds (24h). Rows
21
+ * older than this are pruned on the next write. Pass
22
+ * `appliedTxPruneMaxAgeSeconds: 0` to disable the age backstop.
23
+ */
24
+ export declare const DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS: number;
13
25
  /**
14
26
  * Creates a shared SQLite persistence instance that can be reused by many
15
27
  * collections on the same database. Collection-specific schema versions are
@@ -1,4 +1,4 @@
1
- export { createNodeSQLitePersistence } from './node-persistence.js';
1
+ export { createNodeSQLitePersistence, DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS, DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS, } from './node-persistence.js';
2
2
  export type { BetterSqlite3Database, NodeSQLitePersistenceOptions, NodeSQLiteSchemaMismatchPolicy, } from './node-persistence.js';
3
3
  export { persistedCollectionOptions } from '@tanstack/db-sqlite-persistence-core';
4
4
  export type { PersistedCollectionCoordinator, PersistedCollectionPersistence, } from '@tanstack/db-sqlite-persistence-core';
package/dist/esm/index.js CHANGED
@@ -1,6 +1,8 @@
1
- import { createNodeSQLitePersistence } from "./node-persistence.js";
1
+ import { DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS, DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS, createNodeSQLitePersistence } from "./node-persistence.js";
2
2
  import { persistedCollectionOptions } from "@tanstack/db-sqlite-persistence-core";
3
3
  export {
4
+ DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS,
5
+ DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS,
4
6
  createNodeSQLitePersistence,
5
7
  persistedCollectionOptions
6
8
  };
@@ -10,6 +10,18 @@ type NodeSQLitePersistenceBaseOptions = Omit<SQLiteCoreAdapterOptions, `driver`
10
10
  schemaMismatchPolicy?: NodeSQLiteSchemaMismatchPolicy;
11
11
  };
12
12
  export type NodeSQLitePersistenceOptions = NodeSQLitePersistenceBaseOptions;
13
+ /**
14
+ * Default cap on retained `applied_tx` rows per collection. The log is a
15
+ * replayable cache, so a bounded row count keeps SQLite files from growing
16
+ * without limit. Pass `appliedTxPruneMaxRows: 0` to disable the row cap.
17
+ */
18
+ export declare const DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS = 1000;
19
+ /**
20
+ * Default age backstop for retained `applied_tx` rows, in seconds (24h). Rows
21
+ * older than this are pruned on the next write. Pass
22
+ * `appliedTxPruneMaxAgeSeconds: 0` to disable the age backstop.
23
+ */
24
+ export declare const DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS: number;
13
25
  /**
14
26
  * Creates a shared SQLite persistence instance that can be reused by many
15
27
  * collections on the same database. Collection-specific schema versions are
@@ -1,5 +1,7 @@
1
- import { SingleProcessCoordinator, createSQLiteCorePersistenceAdapter } from "@tanstack/db-sqlite-persistence-core";
1
+ import { DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS as DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS$1, DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS as DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS$1, SingleProcessCoordinator, createSQLiteCorePersistenceAdapter } from "@tanstack/db-sqlite-persistence-core";
2
2
  import { BetterSqlite3SQLiteDriver } from "./node-driver.js";
3
+ const DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS = DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS$1;
4
+ const DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS = DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS$1;
3
5
  function normalizeSchemaMismatchPolicy(policy) {
4
6
  if (policy === `throw`) {
5
7
  return `sync-absent-error`;
@@ -24,8 +26,8 @@ function createInternalSQLiteDriver(options) {
24
26
  }
25
27
  function resolveAdapterBaseOptions(options) {
26
28
  return {
27
- appliedTxPruneMaxRows: options.appliedTxPruneMaxRows,
28
- appliedTxPruneMaxAgeSeconds: options.appliedTxPruneMaxAgeSeconds,
29
+ appliedTxPruneMaxRows: options.appliedTxPruneMaxRows ?? DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS$1,
30
+ appliedTxPruneMaxAgeSeconds: options.appliedTxPruneMaxAgeSeconds ?? DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS$1,
29
31
  pullSinceReloadThreshold: options.pullSinceReloadThreshold
30
32
  };
31
33
  }
@@ -73,6 +75,8 @@ function createNodeSQLitePersistence(options) {
73
75
  };
74
76
  }
75
77
  export {
78
+ DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS,
79
+ DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS,
76
80
  createNodeSQLitePersistence
77
81
  };
78
82
  //# sourceMappingURL=node-persistence.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"node-persistence.js","sources":["../../src/node-persistence.ts"],"sourcesContent":["import {\n SingleProcessCoordinator,\n createSQLiteCorePersistenceAdapter,\n} from '@tanstack/db-sqlite-persistence-core'\nimport { BetterSqlite3SQLiteDriver } from './node-driver'\nimport type {\n PersistedCollectionCoordinator,\n PersistedCollectionMode,\n PersistedCollectionPersistence,\n SQLiteCoreAdapterOptions,\n SQLiteDriver,\n} from '@tanstack/db-sqlite-persistence-core'\nimport type { BetterSqlite3Database } from './node-driver'\n\nexport type { BetterSqlite3Database } from './node-driver'\n\ntype NodeSQLiteCoreSchemaMismatchPolicy =\n | `sync-present-reset`\n | `sync-absent-error`\n | `reset`\n\nexport type NodeSQLiteSchemaMismatchPolicy =\n | NodeSQLiteCoreSchemaMismatchPolicy\n | `throw`\n\ntype NodeSQLitePersistenceBaseOptions = Omit<\n SQLiteCoreAdapterOptions,\n `driver` | `schemaVersion` | `schemaMismatchPolicy`\n> & {\n database: BetterSqlite3Database\n pragmas?: ReadonlyArray<string>\n coordinator?: PersistedCollectionCoordinator\n schemaMismatchPolicy?: NodeSQLiteSchemaMismatchPolicy\n}\n\nexport type NodeSQLitePersistenceOptions = NodeSQLitePersistenceBaseOptions\n\nfunction normalizeSchemaMismatchPolicy(\n policy: NodeSQLiteSchemaMismatchPolicy,\n): NodeSQLiteCoreSchemaMismatchPolicy {\n if (policy === `throw`) {\n return `sync-absent-error`\n }\n\n return policy\n}\n\nfunction resolveSchemaMismatchPolicy(\n explicitPolicy: NodeSQLiteSchemaMismatchPolicy | undefined,\n mode: PersistedCollectionMode,\n): NodeSQLiteCoreSchemaMismatchPolicy {\n if (explicitPolicy) {\n return normalizeSchemaMismatchPolicy(explicitPolicy)\n }\n\n return mode === `sync-present` ? `sync-present-reset` : `sync-absent-error`\n}\n\nfunction createAdapterCacheKey(\n schemaMismatchPolicy: NodeSQLiteCoreSchemaMismatchPolicy,\n schemaVersion: number | undefined,\n): string {\n const schemaVersionKey =\n schemaVersion === undefined ? `schema:default` : `schema:${schemaVersion}`\n return `${schemaMismatchPolicy}|${schemaVersionKey}`\n}\n\nfunction createInternalSQLiteDriver(\n options: NodeSQLitePersistenceOptions,\n): SQLiteDriver {\n return new BetterSqlite3SQLiteDriver({\n database: options.database,\n ...(options.pragmas ? { pragmas: options.pragmas } : {}),\n })\n}\n\nfunction resolveAdapterBaseOptions(\n options: NodeSQLitePersistenceOptions,\n): Omit<\n SQLiteCoreAdapterOptions,\n `driver` | `schemaVersion` | `schemaMismatchPolicy`\n> {\n return {\n appliedTxPruneMaxRows: options.appliedTxPruneMaxRows,\n appliedTxPruneMaxAgeSeconds: options.appliedTxPruneMaxAgeSeconds,\n pullSinceReloadThreshold: options.pullSinceReloadThreshold,\n }\n}\n\n/**\n * Creates a shared SQLite persistence instance that can be reused by many\n * collections on the same database. Collection-specific schema versions are\n * resolved by `persistedCollectionOptions` via `resolvePersistenceForCollection`.\n */\nexport function createNodeSQLitePersistence(\n options: NodeSQLitePersistenceOptions,\n): PersistedCollectionPersistence {\n const { coordinator, schemaMismatchPolicy } = options\n const driver = createInternalSQLiteDriver(options)\n const adapterBaseOptions = resolveAdapterBaseOptions(options)\n const resolvedCoordinator = coordinator ?? new SingleProcessCoordinator()\n const adapterCache = new Map<\n string,\n ReturnType<typeof createSQLiteCorePersistenceAdapter>\n >()\n\n const getAdapterForCollection = (\n mode: PersistedCollectionMode,\n schemaVersion: number | undefined,\n ) => {\n const resolvedSchemaMismatchPolicy = resolveSchemaMismatchPolicy(\n schemaMismatchPolicy,\n mode,\n )\n const cacheKey = createAdapterCacheKey(\n resolvedSchemaMismatchPolicy,\n schemaVersion,\n )\n const cachedAdapter = adapterCache.get(cacheKey)\n if (cachedAdapter) {\n return cachedAdapter\n }\n\n const adapter = createSQLiteCorePersistenceAdapter({\n ...adapterBaseOptions,\n driver,\n schemaMismatchPolicy: resolvedSchemaMismatchPolicy,\n ...(schemaVersion === undefined ? {} : { schemaVersion }),\n })\n adapterCache.set(cacheKey, adapter)\n return adapter\n }\n\n const createCollectionPersistence = (\n mode: PersistedCollectionMode,\n schemaVersion: number | undefined,\n ): PersistedCollectionPersistence => ({\n adapter: getAdapterForCollection(mode, schemaVersion),\n coordinator: resolvedCoordinator,\n })\n\n const defaultPersistence = createCollectionPersistence(\n `sync-absent`,\n undefined,\n )\n\n return {\n ...defaultPersistence,\n resolvePersistenceForCollection: ({ mode, schemaVersion }) =>\n createCollectionPersistence(mode, schemaVersion),\n // Backward compatible fallback for older callers.\n resolvePersistenceForMode: (mode) =>\n createCollectionPersistence(mode, undefined),\n }\n}\n"],"names":[],"mappings":";;AAqCA,SAAS,8BACP,QACoC;AACpC,MAAI,WAAW,SAAS;AACtB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,4BACP,gBACA,MACoC;AACpC,MAAI,gBAAgB;AAClB,WAAO,8BAA8B,cAAc;AAAA,EACrD;AAEA,SAAO,SAAS,iBAAiB,uBAAuB;AAC1D;AAEA,SAAS,sBACP,sBACA,eACQ;AACR,QAAM,mBACJ,kBAAkB,SAAY,mBAAmB,UAAU,aAAa;AAC1E,SAAO,GAAG,oBAAoB,IAAI,gBAAgB;AACpD;AAEA,SAAS,2BACP,SACc;AACd,SAAO,IAAI,0BAA0B;AAAA,IACnC,UAAU,QAAQ;AAAA,IAClB,GAAI,QAAQ,UAAU,EAAE,SAAS,QAAQ,QAAA,IAAY,CAAA;AAAA,EAAC,CACvD;AACH;AAEA,SAAS,0BACP,SAIA;AACA,SAAO;AAAA,IACL,uBAAuB,QAAQ;AAAA,IAC/B,6BAA6B,QAAQ;AAAA,IACrC,0BAA0B,QAAQ;AAAA,EAAA;AAEtC;AAOO,SAAS,4BACd,SACgC;AAChC,QAAM,EAAE,aAAa,qBAAA,IAAyB;AAC9C,QAAM,SAAS,2BAA2B,OAAO;AACjD,QAAM,qBAAqB,0BAA0B,OAAO;AAC5D,QAAM,sBAAsB,eAAe,IAAI,yBAAA;AAC/C,QAAM,mCAAmB,IAAA;AAKzB,QAAM,0BAA0B,CAC9B,MACA,kBACG;AACH,UAAM,+BAA+B;AAAA,MACnC;AAAA,MACA;AAAA,IAAA;AAEF,UAAM,WAAW;AAAA,MACf;AAAA,MACA;AAAA,IAAA;AAEF,UAAM,gBAAgB,aAAa,IAAI,QAAQ;AAC/C,QAAI,eAAe;AACjB,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,mCAAmC;AAAA,MACjD,GAAG;AAAA,MACH;AAAA,MACA,sBAAsB;AAAA,MACtB,GAAI,kBAAkB,SAAY,CAAA,IAAK,EAAE,cAAA;AAAA,IAAc,CACxD;AACD,iBAAa,IAAI,UAAU,OAAO;AAClC,WAAO;AAAA,EACT;AAEA,QAAM,8BAA8B,CAClC,MACA,mBACoC;AAAA,IACpC,SAAS,wBAAwB,MAAM,aAAa;AAAA,IACpD,aAAa;AAAA,EAAA;AAGf,QAAM,qBAAqB;AAAA,IACzB;AAAA,IACA;AAAA,EAAA;AAGF,SAAO;AAAA,IACL,GAAG;AAAA,IACH,iCAAiC,CAAC,EAAE,MAAM,oBACxC,4BAA4B,MAAM,aAAa;AAAA;AAAA,IAEjD,2BAA2B,CAAC,SAC1B,4BAA4B,MAAM,MAAS;AAAA,EAAA;AAEjD;"}
1
+ {"version":3,"file":"node-persistence.js","sources":["../../src/node-persistence.ts"],"sourcesContent":["import {\n DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS as CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS,\n DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS as CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS,\n SingleProcessCoordinator,\n createSQLiteCorePersistenceAdapter,\n} from '@tanstack/db-sqlite-persistence-core'\nimport { BetterSqlite3SQLiteDriver } from './node-driver'\nimport type {\n PersistedCollectionCoordinator,\n PersistedCollectionMode,\n PersistedCollectionPersistence,\n SQLiteCoreAdapterOptions,\n SQLiteDriver,\n} from '@tanstack/db-sqlite-persistence-core'\nimport type { BetterSqlite3Database } from './node-driver'\n\nexport type { BetterSqlite3Database } from './node-driver'\n\ntype NodeSQLiteCoreSchemaMismatchPolicy =\n | `sync-present-reset`\n | `sync-absent-error`\n | `reset`\n\nexport type NodeSQLiteSchemaMismatchPolicy =\n | NodeSQLiteCoreSchemaMismatchPolicy\n | `throw`\n\ntype NodeSQLitePersistenceBaseOptions = Omit<\n SQLiteCoreAdapterOptions,\n `driver` | `schemaVersion` | `schemaMismatchPolicy`\n> & {\n database: BetterSqlite3Database\n pragmas?: ReadonlyArray<string>\n coordinator?: PersistedCollectionCoordinator\n schemaMismatchPolicy?: NodeSQLiteSchemaMismatchPolicy\n}\n\nexport type NodeSQLitePersistenceOptions = NodeSQLitePersistenceBaseOptions\n\n/**\n * Default cap on retained `applied_tx` rows per collection. The log is a\n * replayable cache, so a bounded row count keeps SQLite files from growing\n * without limit. Pass `appliedTxPruneMaxRows: 0` to disable the row cap.\n */\nexport const DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS =\n CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS\n\n/**\n * Default age backstop for retained `applied_tx` rows, in seconds (24h). Rows\n * older than this are pruned on the next write. Pass\n * `appliedTxPruneMaxAgeSeconds: 0` to disable the age backstop.\n */\nexport const DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS =\n CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS\n\nfunction normalizeSchemaMismatchPolicy(\n policy: NodeSQLiteSchemaMismatchPolicy,\n): NodeSQLiteCoreSchemaMismatchPolicy {\n if (policy === `throw`) {\n return `sync-absent-error`\n }\n\n return policy\n}\n\nfunction resolveSchemaMismatchPolicy(\n explicitPolicy: NodeSQLiteSchemaMismatchPolicy | undefined,\n mode: PersistedCollectionMode,\n): NodeSQLiteCoreSchemaMismatchPolicy {\n if (explicitPolicy) {\n return normalizeSchemaMismatchPolicy(explicitPolicy)\n }\n\n return mode === `sync-present` ? `sync-present-reset` : `sync-absent-error`\n}\n\nfunction createAdapterCacheKey(\n schemaMismatchPolicy: NodeSQLiteCoreSchemaMismatchPolicy,\n schemaVersion: number | undefined,\n): string {\n const schemaVersionKey =\n schemaVersion === undefined ? `schema:default` : `schema:${schemaVersion}`\n return `${schemaMismatchPolicy}|${schemaVersionKey}`\n}\n\nfunction createInternalSQLiteDriver(\n options: NodeSQLitePersistenceOptions,\n): SQLiteDriver {\n return new BetterSqlite3SQLiteDriver({\n database: options.database,\n ...(options.pragmas ? { pragmas: options.pragmas } : {}),\n })\n}\n\nfunction resolveAdapterBaseOptions(\n options: NodeSQLitePersistenceOptions,\n): Omit<\n SQLiteCoreAdapterOptions,\n `driver` | `schemaVersion` | `schemaMismatchPolicy`\n> {\n return {\n appliedTxPruneMaxRows:\n options.appliedTxPruneMaxRows ?? CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS,\n appliedTxPruneMaxAgeSeconds:\n options.appliedTxPruneMaxAgeSeconds ??\n CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS,\n pullSinceReloadThreshold: options.pullSinceReloadThreshold,\n }\n}\n\n/**\n * Creates a shared SQLite persistence instance that can be reused by many\n * collections on the same database. Collection-specific schema versions are\n * resolved by `persistedCollectionOptions` via `resolvePersistenceForCollection`.\n */\nexport function createNodeSQLitePersistence(\n options: NodeSQLitePersistenceOptions,\n): PersistedCollectionPersistence {\n const { coordinator, schemaMismatchPolicy } = options\n const driver = createInternalSQLiteDriver(options)\n const adapterBaseOptions = resolveAdapterBaseOptions(options)\n const resolvedCoordinator = coordinator ?? new SingleProcessCoordinator()\n const adapterCache = new Map<\n string,\n ReturnType<typeof createSQLiteCorePersistenceAdapter>\n >()\n\n const getAdapterForCollection = (\n mode: PersistedCollectionMode,\n schemaVersion: number | undefined,\n ) => {\n const resolvedSchemaMismatchPolicy = resolveSchemaMismatchPolicy(\n schemaMismatchPolicy,\n mode,\n )\n const cacheKey = createAdapterCacheKey(\n resolvedSchemaMismatchPolicy,\n schemaVersion,\n )\n const cachedAdapter = adapterCache.get(cacheKey)\n if (cachedAdapter) {\n return cachedAdapter\n }\n\n const adapter = createSQLiteCorePersistenceAdapter({\n ...adapterBaseOptions,\n driver,\n schemaMismatchPolicy: resolvedSchemaMismatchPolicy,\n ...(schemaVersion === undefined ? {} : { schemaVersion }),\n })\n adapterCache.set(cacheKey, adapter)\n return adapter\n }\n\n const createCollectionPersistence = (\n mode: PersistedCollectionMode,\n schemaVersion: number | undefined,\n ): PersistedCollectionPersistence => ({\n adapter: getAdapterForCollection(mode, schemaVersion),\n coordinator: resolvedCoordinator,\n })\n\n const defaultPersistence = createCollectionPersistence(\n `sync-absent`,\n undefined,\n )\n\n return {\n ...defaultPersistence,\n resolvePersistenceForCollection: ({ mode, schemaVersion }) =>\n createCollectionPersistence(mode, schemaVersion),\n // Backward compatible fallback for older callers.\n resolvePersistenceForMode: (mode) =>\n createCollectionPersistence(mode, undefined),\n }\n}\n"],"names":["CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS","CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS"],"mappings":";;AA4CO,MAAM,oCACXA;AAOK,MAAM,2CACXC;AAEF,SAAS,8BACP,QACoC;AACpC,MAAI,WAAW,SAAS;AACtB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,SAAS,4BACP,gBACA,MACoC;AACpC,MAAI,gBAAgB;AAClB,WAAO,8BAA8B,cAAc;AAAA,EACrD;AAEA,SAAO,SAAS,iBAAiB,uBAAuB;AAC1D;AAEA,SAAS,sBACP,sBACA,eACQ;AACR,QAAM,mBACJ,kBAAkB,SAAY,mBAAmB,UAAU,aAAa;AAC1E,SAAO,GAAG,oBAAoB,IAAI,gBAAgB;AACpD;AAEA,SAAS,2BACP,SACc;AACd,SAAO,IAAI,0BAA0B;AAAA,IACnC,UAAU,QAAQ;AAAA,IAClB,GAAI,QAAQ,UAAU,EAAE,SAAS,QAAQ,QAAA,IAAY,CAAA;AAAA,EAAC,CACvD;AACH;AAEA,SAAS,0BACP,SAIA;AACA,SAAO;AAAA,IACL,uBACE,QAAQ,yBAAyBD;AAAAA,IACnC,6BACE,QAAQ,+BACRC;AAAAA,IACF,0BAA0B,QAAQ;AAAA,EAAA;AAEtC;AAOO,SAAS,4BACd,SACgC;AAChC,QAAM,EAAE,aAAa,qBAAA,IAAyB;AAC9C,QAAM,SAAS,2BAA2B,OAAO;AACjD,QAAM,qBAAqB,0BAA0B,OAAO;AAC5D,QAAM,sBAAsB,eAAe,IAAI,yBAAA;AAC/C,QAAM,mCAAmB,IAAA;AAKzB,QAAM,0BAA0B,CAC9B,MACA,kBACG;AACH,UAAM,+BAA+B;AAAA,MACnC;AAAA,MACA;AAAA,IAAA;AAEF,UAAM,WAAW;AAAA,MACf;AAAA,MACA;AAAA,IAAA;AAEF,UAAM,gBAAgB,aAAa,IAAI,QAAQ;AAC/C,QAAI,eAAe;AACjB,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,mCAAmC;AAAA,MACjD,GAAG;AAAA,MACH;AAAA,MACA,sBAAsB;AAAA,MACtB,GAAI,kBAAkB,SAAY,CAAA,IAAK,EAAE,cAAA;AAAA,IAAc,CACxD;AACD,iBAAa,IAAI,UAAU,OAAO;AAClC,WAAO;AAAA,EACT;AAEA,QAAM,8BAA8B,CAClC,MACA,mBACoC;AAAA,IACpC,SAAS,wBAAwB,MAAM,aAAa;AAAA,IACpD,aAAa;AAAA,EAAA;AAGf,QAAM,qBAAqB;AAAA,IACzB;AAAA,IACA;AAAA,EAAA;AAGF,SAAO;AAAA,IACL,GAAG;AAAA,IACH,iCAAiC,CAAC,EAAE,MAAM,oBACxC,4BAA4B,MAAM,aAAa;AAAA;AAAA,IAEjD,2BAA2B,CAAC,SAC1B,4BAA4B,MAAM,MAAS;AAAA,EAAA;AAEjD;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/node-db-sqlite-persistence",
3
- "version": "0.1.11",
3
+ "version": "0.2.1",
4
4
  "description": "Node SQLite persisted collection adapter for TanStack DB",
5
5
  "author": "TanStack Team",
6
6
  "license": "MIT",
@@ -41,7 +41,7 @@
41
41
  ],
42
42
  "dependencies": {
43
43
  "better-sqlite3": "^12.6.2",
44
- "@tanstack/db-sqlite-persistence-core": "0.1.11"
44
+ "@tanstack/db-sqlite-persistence-core": "0.2.1"
45
45
  },
46
46
  "peerDependencies": {
47
47
  "typescript": ">=4.7"
package/src/index.ts CHANGED
@@ -1,4 +1,8 @@
1
- export { createNodeSQLitePersistence } from './node-persistence'
1
+ export {
2
+ createNodeSQLitePersistence,
3
+ DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS,
4
+ DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS,
5
+ } from './node-persistence'
2
6
  export type {
3
7
  BetterSqlite3Database,
4
8
  NodeSQLitePersistenceOptions,
@@ -1,4 +1,6 @@
1
1
  import {
2
+ DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS as CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS,
3
+ DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS as CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS,
2
4
  SingleProcessCoordinator,
3
5
  createSQLiteCorePersistenceAdapter,
4
6
  } from '@tanstack/db-sqlite-persistence-core'
@@ -35,6 +37,22 @@ type NodeSQLitePersistenceBaseOptions = Omit<
35
37
 
36
38
  export type NodeSQLitePersistenceOptions = NodeSQLitePersistenceBaseOptions
37
39
 
40
+ /**
41
+ * Default cap on retained `applied_tx` rows per collection. The log is a
42
+ * replayable cache, so a bounded row count keeps SQLite files from growing
43
+ * without limit. Pass `appliedTxPruneMaxRows: 0` to disable the row cap.
44
+ */
45
+ export const DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS =
46
+ CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS
47
+
48
+ /**
49
+ * Default age backstop for retained `applied_tx` rows, in seconds (24h). Rows
50
+ * older than this are pruned on the next write. Pass
51
+ * `appliedTxPruneMaxAgeSeconds: 0` to disable the age backstop.
52
+ */
53
+ export const DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS =
54
+ CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS
55
+
38
56
  function normalizeSchemaMismatchPolicy(
39
57
  policy: NodeSQLiteSchemaMismatchPolicy,
40
58
  ): NodeSQLiteCoreSchemaMismatchPolicy {
@@ -81,8 +99,11 @@ function resolveAdapterBaseOptions(
81
99
  `driver` | `schemaVersion` | `schemaMismatchPolicy`
82
100
  > {
83
101
  return {
84
- appliedTxPruneMaxRows: options.appliedTxPruneMaxRows,
85
- appliedTxPruneMaxAgeSeconds: options.appliedTxPruneMaxAgeSeconds,
102
+ appliedTxPruneMaxRows:
103
+ options.appliedTxPruneMaxRows ?? CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_ROWS,
104
+ appliedTxPruneMaxAgeSeconds:
105
+ options.appliedTxPruneMaxAgeSeconds ??
106
+ CORE_DEFAULT_APPLIED_TX_PRUNE_MAX_AGE_SECONDS,
86
107
  pullSinceReloadThreshold: options.pullSinceReloadThreshold,
87
108
  }
88
109
  }