@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 +29 -0
- package/dist/cjs/index.cjs +2 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +1 -1
- package/dist/cjs/node-persistence.cjs +6 -2
- package/dist/cjs/node-persistence.cjs.map +1 -1
- package/dist/cjs/node-persistence.d.cts +12 -0
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +3 -1
- package/dist/esm/node-persistence.d.ts +12 -0
- package/dist/esm/node-persistence.js +7 -3
- package/dist/esm/node-persistence.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +5 -1
- package/src/node-persistence.ts +23 -2
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`.
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -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,
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
|
package/dist/cjs/index.d.cts
CHANGED
|
@@ -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
|
|
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
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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 {
|
|
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,
|
package/src/node-persistence.ts
CHANGED
|
@@ -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:
|
|
85
|
-
|
|
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
|
}
|