@framers/sql-storage-adapter 0.6.13 → 0.6.14
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 +20 -3
- package/dist/adapters/capacitorSqliteAdapter.d.ts +42 -0
- package/dist/adapters/capacitorSqliteAdapter.d.ts.map +1 -1
- package/dist/adapters/capacitorSqliteAdapter.js +139 -21
- package/dist/adapters/capacitorSqliteAdapter.js.map +1 -1
- package/dist/adapters/indexedDbAdapter.d.ts +89 -10
- package/dist/adapters/indexedDbAdapter.d.ts.map +1 -1
- package/dist/adapters/indexedDbAdapter.js +265 -58
- package/dist/adapters/indexedDbAdapter.js.map +1 -1
- package/dist/core/database.d.ts +12 -4
- package/dist/core/database.d.ts.map +1 -1
- package/dist/core/database.js +17 -8
- package/dist/core/database.js.map +1 -1
- package/dist/core/resolver.d.ts +15 -5
- package/dist/core/resolver.d.ts.map +1 -1
- package/dist/core/resolver.js +43 -7
- package/dist/core/resolver.js.map +1 -1
- package/dist/shared/connectionGate.d.ts +32 -9
- package/dist/shared/connectionGate.d.ts.map +1 -1
- package/dist/shared/connectionGate.js +31 -12
- package/dist/shared/connectionGate.js.map +1 -1
- package/dist/shared/postgresTarget.d.ts +10 -0
- package/dist/shared/postgresTarget.d.ts.map +1 -0
- package/dist/shared/postgresTarget.js +13 -0
- package/dist/shared/postgresTarget.js.map +1 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -131,13 +131,13 @@ See [Platform Strategy Guide](./PLATFORM_STRATEGY.md) for detailed pros/cons and
|
|
|
131
131
|
|
|
132
132
|
| Adapter | Package | Ideal for | Pros | Considerations |
|
|
133
133
|
| --- | --- | --- | --- | --- |
|
|
134
|
-
| **🆕 `electron`** | bundled | **Electron desktop apps** | IPC bridge, multi-window, WAL, auto-migrations, crash recovery | Requires Electron runtime |
|
|
134
|
+
| **🆕 `electron`** | bundled | **Electron desktop apps** | IPC bridge, multi-window, WAL, auto-migrations, crash recovery | Requires Electron runtime; create it from `@framers/sql-storage-adapter/electron` (the resolver does not build the `electron-main` and `electron-renderer` kinds) |
|
|
135
135
|
| **🆕 `indexeddb`** | bundled (sql.js) | **Browsers, PWAs** | sql.js + IndexedDB persistence wrapper, browser-native storage, 50MB-1GB+ quota, offline-first | IndexedDB quotas vary, WASM overhead (sql.js), not a separate SQL engine |
|
|
136
136
|
| `better-sqlite3` | `better-sqlite3` | Node/Electron, CLI, CI | Native performance, transactional semantics, WAL support | Needs native toolchain; version must match Node ABI; 13.x needs Node-API 10 (Node.js 22.14+, Electron 35+) |
|
|
137
137
|
| `postgres` | `pg` | Hosted or on-prem PostgreSQL | Connection pooling, rich SQL features, cloud friendly | Requires `DATABASE_URL`/credentials |
|
|
138
138
|
| `sqljs` | bundled | Browsers, serverless edge, native fallback | Pure WASM SQLite, no native deps, optional filesystem persistence | Write performance limited vs native, in-memory by default |
|
|
139
139
|
| `capacitor` | `@capacitor-community/sqlite` | Mobile (iOS/Android, Capacitor) | Native SQLite on mobile, encryption | Requires Capacitor runtime |
|
|
140
|
-
| `memory` |
|
|
140
|
+
| `memory` | bundled (sql.js) | Unit tests, storybooks, constrained sandboxes | Zero dependencies, instant startup | The resolver builds the sql.js adapter for it, as for `sqljs`: in memory in a browser, persisted to the resolver's file path on Node |
|
|
141
141
|
|
|
142
142
|
### Platform Priorities
|
|
143
143
|
|
|
@@ -243,9 +243,24 @@ await sync.connect();
|
|
|
243
243
|
- environment variables (`STORAGE_ADAPTER`, `DATABASE_URL`),
|
|
244
244
|
- runtime hints (Capacitor detection, browser globals, IndexedDB availability).
|
|
245
245
|
- Adapters are attempted in priority order until one opens successfully; a `StorageResolutionError` includes the full failure chain.
|
|
246
|
+
- The resolver builds `postgres`, `better-sqlite3`, `capacitor`, `indexeddb` and `sqljs`, and builds sql.js for `memory`. Any other kind (`electron-main`, `electron-renderer`, `supabase`, or an unknown name, from `priority` or `STORAGE_ADAPTER`) fails as a candidate with an error that names it, and the next candidate is tried.
|
|
247
|
+
- On Node, `createDatabase({ url })`, `createDatabase({ postgres })` and `connectDatabase()` open PostgreSQL, with every Postgres option (pool size, SSL, timeouts, application name, or host, port, database, user and password without a connection string) passed on, and do not fall back to SQLite. In a browser and on Deno, `createDatabase()` opens sql.js whatever the options say. `DATABASE_URL` in the environment does not change what `createDatabase()` picks; `resolveStorageAdapter()` without a `priority` tries Postgres first when it is set.
|
|
246
248
|
- Provide `priority: ['indexeddb', 'sqljs']` for browser bundles or tests where native modules shouldn't load.
|
|
247
249
|
- Use `createCloudBackupManager` for S3-compatible backups with gzip compression and retention limits.
|
|
248
250
|
|
|
251
|
+
### Transactions
|
|
252
|
+
|
|
253
|
+
`transaction(fn)` commits when `fn` resolves and rolls back when it throws. Run the callback's statements through the handle it receives:
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
await db.transaction(async (trx) => {
|
|
257
|
+
await trx.run('UPDATE accounts SET balance = balance - ? WHERE id = ?', [100, 'a']);
|
|
258
|
+
await trx.run('UPDATE accounts SET balance = balance + ? WHERE id = ?', [100, 'b']);
|
|
259
|
+
});
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
The IndexedDB, Capacitor and better-sqlite3 adapters run every transaction on one connection, so they run transactions one at a time, and a statement from another caller waits until the open transaction ends: it neither joins the transaction (and vanishes in its rollback) nor reads what the transaction has not committed. A browser or a WebView has no async context to tell the callback's own statements apart, so on the IndexedDB and Capacitor adapters a statement the callback issues through the adapter itself, not through its handle, waits for the transaction too. The two then wait on each other, and the adapter logs a warning after 10 seconds. (On Node, better-sqlite3 tells them apart with `AsyncLocalStorage`.) Inside a callback, run every statement through the handle, and do not await work that itself needs the database.
|
|
263
|
+
|
|
249
264
|
### IndexedDB-Specific Config
|
|
250
265
|
|
|
251
266
|
```typescript
|
|
@@ -269,6 +284,8 @@ await adapter.open();
|
|
|
269
284
|
- ✅ Export/import (Uint8Array SQLite file format)
|
|
270
285
|
- ✅ Auto-save with batching (reduce IDB overhead)
|
|
271
286
|
|
|
287
|
+
**When it saves:** every `saveIntervalMs`, the adapter writes the database image to IndexedDB if anything changed. It skips the tick while a transaction is open, its own or one begun with `BEGIN`, because sql.js's export closes and reopens the connection, which would end the transaction; the next tick saves it once it has committed. A save counts as done when IndexedDB commits it, not when the put request succeeds. A save that fails or aborts is reported once, and the next tick tries again. A write made while a save is in flight is saved by the next one. A transaction's commit marks its writes for saving, including writes made through `all()` or `get()` (`INSERT ... RETURNING`). `close()` rolls back a transaction still open and saves the committed state. `importDatabase()` saves the imported image before it resolves. `exportDatabase()` throws while a transaction is open.
|
|
288
|
+
|
|
272
289
|
**Why IndexedDB Adapter vs sql.js Adapter?**
|
|
273
290
|
|
|
274
291
|
| Feature | IndexedDB Adapter | sql.js Adapter |
|
|
@@ -503,7 +520,7 @@ On Postgres, `features.exporter` requires a Node runtime plus an adapter that wa
|
|
|
503
520
|
## CI, Releases, and Badges
|
|
504
521
|
|
|
505
522
|
- GitHub Actions workflows:
|
|
506
|
-
- `ci.yml` runs on pushes and pull requests to `master`: lint, type check, tests with coverage and the build, then it packs the package, installs the tarball into a new ES module project and type-checks a consumer with `--module nodenext --moduleResolution nodenext`.
|
|
523
|
+
- `ci.yml` runs on pushes and pull requests to `master`: lint, type check, tests with coverage and the build, then it packs the package, installs the tarball into a new ES module project and type-checks a consumer with `--module nodenext --moduleResolution nodenext`. The job starts a PostgreSQL 16 service, and the specs that need a server read its URL from `POSTGRES_TEST_URL`.
|
|
507
524
|
- `release.yml` publishes new versions to npm, tags the commit (`vX.Y.Z`), and creates/updates the GitHub Release when `CHANGELOG.md` and `package.json` bump the version.
|
|
508
525
|
- Check badge health whenever builds fail:
|
|
509
526
|
- CI badge should be green for `master`.
|
|
@@ -11,6 +11,12 @@ export interface CapacitorAdapterOptions {
|
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
13
|
* Adapter using @capacitor-community/sqlite for native mobile targets.
|
|
14
|
+
*
|
|
15
|
+
* Transactions use the plugin's beginTransaction, commitTransaction and
|
|
16
|
+
* rollbackTransaction (plugin 5.0.7 and later). The plugin runs every other
|
|
17
|
+
* execute and run call in a transaction of its own, which cannot nest in an
|
|
18
|
+
* open one, so the statements of a transaction's callback go to the plugin
|
|
19
|
+
* with `transaction` false.
|
|
14
20
|
*/
|
|
15
21
|
export declare class CapacitorSqliteAdapter implements StorageAdapter {
|
|
16
22
|
private readonly options;
|
|
@@ -19,14 +25,50 @@ export declare class CapacitorSqliteAdapter implements StorageAdapter {
|
|
|
19
25
|
private plugin;
|
|
20
26
|
private connection;
|
|
21
27
|
private dbName;
|
|
28
|
+
/** The connection is shared, so transaction() runs one callback at a time. */
|
|
29
|
+
private readonly runSerializedTransaction;
|
|
30
|
+
/**
|
|
31
|
+
* Holds statements from outside an open transaction until it ends. A WebView
|
|
32
|
+
* has no async context to tell the callback's own statements apart, so the
|
|
33
|
+
* callback's handle is the only way into an open transaction.
|
|
34
|
+
*/
|
|
35
|
+
private readonly gate;
|
|
36
|
+
/** Statements sent to the plugin from outside a transaction and not yet answered. */
|
|
37
|
+
private readonly inFlight;
|
|
38
|
+
private longWaitReported;
|
|
39
|
+
private readonly longWait;
|
|
22
40
|
constructor(options?: CapacitorAdapterOptions);
|
|
23
41
|
open(options?: StorageOpenOptions): Promise<void>;
|
|
24
42
|
run(statement: string, parameters?: StorageParameters): Promise<StorageRunResult>;
|
|
25
43
|
get<T>(statement: string, parameters?: StorageParameters): Promise<T | null>;
|
|
26
44
|
all<T>(statement: string, parameters?: StorageParameters): Promise<T[]>;
|
|
27
45
|
exec(script: string): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Executes a callback within a database transaction.
|
|
48
|
+
*
|
|
49
|
+
* Callbacks run one at a time, since every transaction shares the one
|
|
50
|
+
* connection. The callback's statements go through the handle it receives;
|
|
51
|
+
* a statement issued through the adapter itself while the callback runs
|
|
52
|
+
* waits until the transaction ends, so a callback must not await one.
|
|
53
|
+
*/
|
|
28
54
|
transaction<T>(fn: (trx: StorageAdapter) => Promise<T>): Promise<T>;
|
|
29
55
|
close(): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* The statements of one transaction's handle: they carry the transaction's
|
|
58
|
+
* token, so the gate admits them while the transaction is open, and run
|
|
59
|
+
* inside the plugin's open transaction.
|
|
60
|
+
*/
|
|
61
|
+
private handleStatements;
|
|
62
|
+
/**
|
|
63
|
+
* @param ownTransaction - true for a statement from outside a transaction:
|
|
64
|
+
* the plugin runs it in a transaction of its own, as it always has.
|
|
65
|
+
*/
|
|
66
|
+
private runNow;
|
|
67
|
+
private allNow;
|
|
68
|
+
private execNow;
|
|
69
|
+
/** Keeps a statement sent from outside a transaction in `inFlight` until it answers. */
|
|
70
|
+
private track;
|
|
71
|
+
private reportLongWait;
|
|
30
72
|
private ensureConnection;
|
|
31
73
|
}
|
|
32
74
|
export declare const createCapacitorSqliteAdapter: (options?: CapacitorAdapterOptions) => StorageAdapter;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capacitorSqliteAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/capacitorSqliteAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"capacitorSqliteAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/capacitorSqliteAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,mBAAmB,CAAC;AAa3B,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAyDD;;;;;;;;GAQG;AACH,qBAAa,sBAAuB,YAAW,cAAc;IA4B/C,OAAO,CAAC,QAAQ,CAAC,OAAO;IA3BpC,SAAgB,IAAI,sBAAsB;IAC1C,SAAgB,YAAY,EAAE,WAAW,CAAC,iBAAiB,CAAC,CAKzD;IAEH,OAAO,CAAC,MAAM,CAAsC;IACpD,OAAO,CAAC,UAAU,CAAmC;IACrD,OAAO,CAAC,MAAM,CAAS;IACvB,8EAA8E;IAC9E,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAuC;IAChF;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA0D;IAC/E,qFAAqF;IACrF,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA+B;IACxD,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAGvB;gBAE2B,OAAO,GAAE,uBAA4B;IAIrD,IAAI,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BjD,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAIjF,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAK5E,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAIvE,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD;;;;;;;OAOG;IACU,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IA8BnE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAOnC;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAmBxB;;;OAGG;YACW,MAAM;YAUN,MAAM;YAON,OAAO;IAKrB,wFAAwF;IACxF,OAAO,CAAC,KAAK;IASb,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,gBAAgB;CAMzB;AAED,eAAO,MAAM,4BAA4B,aAAc,uBAAuB,KAAG,cAC5C,CAAC"}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import { normaliseParameters } from '../shared/parameterUtils.js';
|
|
2
|
+
import { createSerializedTransactionRunner, createSharedConnectionTransactionAdapter, } from '../shared/serializedTransaction.js';
|
|
3
|
+
import { createConnectionGate, whenAdmitted } from '../shared/connectionGate.js';
|
|
4
|
+
/** How long a statement waits for an open transaction before the adapter warns. */
|
|
5
|
+
const LONG_WAIT_MS = 10000;
|
|
2
6
|
const isCapacitorPlugin = (value) => {
|
|
3
7
|
if (!value || typeof value !== 'object') {
|
|
4
8
|
return false;
|
|
@@ -28,8 +32,30 @@ const loadCapacitorSqlite = async () => {
|
|
|
28
32
|
return null;
|
|
29
33
|
}
|
|
30
34
|
};
|
|
35
|
+
/**
|
|
36
|
+
* The plugin answers run() with `{ changes: { changes, lastId } }`
|
|
37
|
+
* (`capSQLiteChanges`); a flat `{ changes, lastId }` is read as well.
|
|
38
|
+
*/
|
|
39
|
+
const toRunResult = (answer) => {
|
|
40
|
+
const outer = (answer ?? {});
|
|
41
|
+
const inner = typeof outer.changes === 'object' && outer.changes !== null
|
|
42
|
+
? outer.changes
|
|
43
|
+
: outer;
|
|
44
|
+
const changes = typeof inner.changes === 'number' ? inner.changes : 0;
|
|
45
|
+
const lastId = inner.lastId;
|
|
46
|
+
return {
|
|
47
|
+
changes,
|
|
48
|
+
lastInsertRowid: typeof lastId === 'number' || typeof lastId === 'string' ? lastId : null,
|
|
49
|
+
};
|
|
50
|
+
};
|
|
31
51
|
/**
|
|
32
52
|
* Adapter using @capacitor-community/sqlite for native mobile targets.
|
|
53
|
+
*
|
|
54
|
+
* Transactions use the plugin's beginTransaction, commitTransaction and
|
|
55
|
+
* rollbackTransaction (plugin 5.0.7 and later). The plugin runs every other
|
|
56
|
+
* execute and run call in a transaction of its own, which cannot nest in an
|
|
57
|
+
* open one, so the statements of a transaction's callback go to the plugin
|
|
58
|
+
* with `transaction` false.
|
|
33
59
|
*/
|
|
34
60
|
export class CapacitorSqliteAdapter {
|
|
35
61
|
constructor(options = {}) {
|
|
@@ -43,6 +69,21 @@ export class CapacitorSqliteAdapter {
|
|
|
43
69
|
]);
|
|
44
70
|
this.plugin = null;
|
|
45
71
|
this.connection = null;
|
|
72
|
+
/** The connection is shared, so transaction() runs one callback at a time. */
|
|
73
|
+
this.runSerializedTransaction = createSerializedTransactionRunner();
|
|
74
|
+
/**
|
|
75
|
+
* Holds statements from outside an open transaction until it ends. A WebView
|
|
76
|
+
* has no async context to tell the callback's own statements apart, so the
|
|
77
|
+
* callback's handle is the only way into an open transaction.
|
|
78
|
+
*/
|
|
79
|
+
this.gate = createConnectionGate(null, { withoutContext: 'wait' });
|
|
80
|
+
/** Statements sent to the plugin from outside a transaction and not yet answered. */
|
|
81
|
+
this.inFlight = new Set();
|
|
82
|
+
this.longWaitReported = false;
|
|
83
|
+
this.longWait = {
|
|
84
|
+
afterMs: LONG_WAIT_MS,
|
|
85
|
+
onLongWait: () => this.reportLongWait(),
|
|
86
|
+
};
|
|
46
87
|
this.dbName = options.database ?? 'app';
|
|
47
88
|
}
|
|
48
89
|
async open(options) {
|
|
@@ -69,37 +110,56 @@ export class CapacitorSqliteAdapter {
|
|
|
69
110
|
}
|
|
70
111
|
}
|
|
71
112
|
async run(statement, parameters) {
|
|
72
|
-
|
|
73
|
-
const { positional } = normaliseParameters(parameters);
|
|
74
|
-
const result = await conn.run(statement, positional ?? []);
|
|
75
|
-
return { changes: result.changes ?? 0, lastInsertRowid: result.lastId ?? null };
|
|
113
|
+
return whenAdmitted(this.gate, () => this.track(this.runNow(statement, parameters, true)), undefined, this.longWait);
|
|
76
114
|
}
|
|
77
115
|
async get(statement, parameters) {
|
|
78
116
|
const rows = await this.all(statement, parameters);
|
|
79
117
|
return rows.length > 0 ? rows[0] : null;
|
|
80
118
|
}
|
|
81
119
|
async all(statement, parameters) {
|
|
82
|
-
|
|
83
|
-
const { positional } = normaliseParameters(parameters);
|
|
84
|
-
const result = await conn.query(statement, positional ?? []);
|
|
85
|
-
return (result.values ?? []);
|
|
120
|
+
return whenAdmitted(this.gate, () => this.track(this.allNow(statement, parameters)), undefined, this.longWait);
|
|
86
121
|
}
|
|
87
122
|
async exec(script) {
|
|
88
|
-
|
|
89
|
-
await conn.execute(script);
|
|
123
|
+
return whenAdmitted(this.gate, () => this.track(this.execNow(script, true)), undefined, this.longWait);
|
|
90
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* Executes a callback within a database transaction.
|
|
127
|
+
*
|
|
128
|
+
* Callbacks run one at a time, since every transaction shares the one
|
|
129
|
+
* connection. The callback's statements go through the handle it receives;
|
|
130
|
+
* a statement issued through the adapter itself while the callback runs
|
|
131
|
+
* waits until the transaction ends, so a callback must not await one.
|
|
132
|
+
*/
|
|
91
133
|
async transaction(fn) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
134
|
+
this.ensureConnection();
|
|
135
|
+
const queued = setTimeout(() => this.reportLongWait(), LONG_WAIT_MS);
|
|
136
|
+
return this.runSerializedTransaction(() => {
|
|
137
|
+
clearTimeout(queued);
|
|
138
|
+
return this.gate.hold(async (token) => {
|
|
139
|
+
// The gate now holds new statements back; let the ones already sent
|
|
140
|
+
// answer before the transaction begins.
|
|
141
|
+
await Promise.allSettled([...this.inFlight]);
|
|
142
|
+
const conn = this.ensureConnection();
|
|
143
|
+
// Outside the try: when beginTransaction fails, no transaction of this
|
|
144
|
+
// call is open to roll back.
|
|
145
|
+
await conn.beginTransaction();
|
|
146
|
+
const transactionAdapter = createSharedConnectionTransactionAdapter(this.handleStatements(token));
|
|
147
|
+
try {
|
|
148
|
+
const result = await fn(transactionAdapter);
|
|
149
|
+
await conn.commitTransaction();
|
|
150
|
+
return result;
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
try {
|
|
154
|
+
await conn.rollbackTransaction();
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
// The transaction already ended.
|
|
158
|
+
}
|
|
159
|
+
throw error;
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
});
|
|
103
163
|
}
|
|
104
164
|
async close() {
|
|
105
165
|
if (this.connection) {
|
|
@@ -107,6 +167,64 @@ export class CapacitorSqliteAdapter {
|
|
|
107
167
|
this.connection = null;
|
|
108
168
|
}
|
|
109
169
|
}
|
|
170
|
+
/**
|
|
171
|
+
* The statements of one transaction's handle: they carry the transaction's
|
|
172
|
+
* token, so the gate admits them while the transaction is open, and run
|
|
173
|
+
* inside the plugin's open transaction.
|
|
174
|
+
*/
|
|
175
|
+
handleStatements(token) {
|
|
176
|
+
return {
|
|
177
|
+
kind: this.kind,
|
|
178
|
+
capabilities: this.capabilities,
|
|
179
|
+
open: async () => { },
|
|
180
|
+
close: async () => { },
|
|
181
|
+
run: (statement, parameters) => whenAdmitted(this.gate, () => this.runNow(statement, parameters, false), token),
|
|
182
|
+
get: async (statement, parameters) => {
|
|
183
|
+
const rows = await whenAdmitted(this.gate, () => this.allNow(statement, parameters), token);
|
|
184
|
+
return rows.length > 0 ? rows[0] : null;
|
|
185
|
+
},
|
|
186
|
+
all: (statement, parameters) => whenAdmitted(this.gate, () => this.allNow(statement, parameters), token),
|
|
187
|
+
exec: (script) => whenAdmitted(this.gate, () => this.execNow(script, false), token),
|
|
188
|
+
// The handle answers a nested transaction() itself and never calls this.
|
|
189
|
+
transaction: (fn) => fn(this),
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* @param ownTransaction - true for a statement from outside a transaction:
|
|
194
|
+
* the plugin runs it in a transaction of its own, as it always has.
|
|
195
|
+
*/
|
|
196
|
+
async runNow(statement, parameters, ownTransaction) {
|
|
197
|
+
const conn = this.ensureConnection();
|
|
198
|
+
const { positional } = normaliseParameters(parameters);
|
|
199
|
+
return toRunResult(await conn.run(statement, positional ?? [], ownTransaction));
|
|
200
|
+
}
|
|
201
|
+
async allNow(statement, parameters) {
|
|
202
|
+
const conn = this.ensureConnection();
|
|
203
|
+
const { positional } = normaliseParameters(parameters);
|
|
204
|
+
const result = await conn.query(statement, positional ?? []);
|
|
205
|
+
return (result.values ?? []);
|
|
206
|
+
}
|
|
207
|
+
async execNow(script, ownTransaction) {
|
|
208
|
+
const conn = this.ensureConnection();
|
|
209
|
+
await conn.execute(script, ownTransaction);
|
|
210
|
+
}
|
|
211
|
+
/** Keeps a statement sent from outside a transaction in `inFlight` until it answers. */
|
|
212
|
+
track(sent) {
|
|
213
|
+
this.inFlight.add(sent);
|
|
214
|
+
const forget = () => {
|
|
215
|
+
this.inFlight.delete(sent);
|
|
216
|
+
};
|
|
217
|
+
sent.then(forget, forget);
|
|
218
|
+
return sent;
|
|
219
|
+
}
|
|
220
|
+
reportLongWait() {
|
|
221
|
+
if (this.longWaitReported)
|
|
222
|
+
return;
|
|
223
|
+
this.longWaitReported = true;
|
|
224
|
+
console.warn(`[StorageAdapter] A Capacitor SQLite statement has waited ${LONG_WAIT_MS / 1000} s for an open transaction to end. ` +
|
|
225
|
+
"Inside a transaction() callback, run statements through the callback's handle: one run through the adapter " +
|
|
226
|
+
'itself waits for the transaction, and the transaction waits for it.');
|
|
227
|
+
}
|
|
110
228
|
ensureConnection() {
|
|
111
229
|
if (!this.connection) {
|
|
112
230
|
throw new Error('Storage adapter not opened. Call open() before executing statements.');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capacitorSqliteAdapter.js","sourceRoot":"","sources":["../../src/adapters/capacitorSqliteAdapter.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"capacitorSqliteAdapter.js","sourceRoot":"","sources":["../../src/adapters/capacitorSqliteAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -134,7 +134,32 @@ export declare class IndexedDbAdapter implements StorageAdapter {
|
|
|
134
134
|
private db;
|
|
135
135
|
private idb;
|
|
136
136
|
private saveTimer;
|
|
137
|
-
|
|
137
|
+
/** Bumped by every statement that can change the database. */
|
|
138
|
+
private writeGeneration;
|
|
139
|
+
/** The generation the last completed save exported; the writes after it are unsaved. */
|
|
140
|
+
private savedGeneration;
|
|
141
|
+
/** The save in progress, if any. */
|
|
142
|
+
private saving;
|
|
143
|
+
/** Whether a failed auto-save has been reported since the last one that succeeded. */
|
|
144
|
+
private saveFailureReported;
|
|
145
|
+
/** Set while close() runs: no statement or transaction starts. */
|
|
146
|
+
private closing;
|
|
147
|
+
/** The close() in progress, which a second call waits for. */
|
|
148
|
+
private closeRun;
|
|
149
|
+
private longWaitReported;
|
|
150
|
+
/**
|
|
151
|
+
* The connection is shared, so transaction() runs one callback at a time.
|
|
152
|
+
*/
|
|
153
|
+
private readonly runSerializedTransaction;
|
|
154
|
+
/**
|
|
155
|
+
* Holds statements from outside an open transaction until it ends, so they
|
|
156
|
+
* neither join it (and vanish in its rollback) nor read what it has not
|
|
157
|
+
* committed. Browsers have no async context to tell the callback's own
|
|
158
|
+
* statements apart, so the callback's handle is the only way into an open
|
|
159
|
+
* transaction: a statement through the adapter itself waits.
|
|
160
|
+
*/
|
|
161
|
+
private readonly gate;
|
|
162
|
+
private readonly longWait;
|
|
138
163
|
private readonly dbName;
|
|
139
164
|
private readonly storeName;
|
|
140
165
|
private readonly autoSave;
|
|
@@ -157,6 +182,7 @@ export declare class IndexedDbAdapter implements StorageAdapter {
|
|
|
157
182
|
* @returns Result with changes count and last insert row ID
|
|
158
183
|
*/
|
|
159
184
|
run(statement: string, parameters?: StorageParameters): Promise<StorageRunResult>;
|
|
185
|
+
private runNow;
|
|
160
186
|
/**
|
|
161
187
|
* Executes a SQL query and returns the first row.
|
|
162
188
|
* @param statement SELECT statement
|
|
@@ -171,17 +197,32 @@ export declare class IndexedDbAdapter implements StorageAdapter {
|
|
|
171
197
|
* @returns Array of result rows as objects
|
|
172
198
|
*/
|
|
173
199
|
all<T>(statement: string, parameters?: StorageParameters): Promise<T[]>;
|
|
200
|
+
private allNow;
|
|
174
201
|
/**
|
|
175
202
|
* Executes a script containing multiple SQL statements.
|
|
176
203
|
*/
|
|
177
204
|
exec(script: string): Promise<void>;
|
|
205
|
+
private execNow;
|
|
178
206
|
/**
|
|
179
207
|
* Executes a callback within a database transaction.
|
|
208
|
+
*
|
|
209
|
+
* Callbacks run one at a time, since every transaction shares the one
|
|
210
|
+
* connection. The callback's statements go through the handle it receives;
|
|
211
|
+
* a statement issued through the adapter itself while the callback runs
|
|
212
|
+
* waits until the transaction ends, so a callback must not await one. The
|
|
213
|
+
* auto-save tick does not save while a transaction is open.
|
|
180
214
|
*/
|
|
181
215
|
transaction<T>(fn: (trx: StorageAdapter) => Promise<T>): Promise<T>;
|
|
182
216
|
/**
|
|
183
|
-
*
|
|
184
|
-
* so
|
|
217
|
+
* The statements of one transaction's handle: they carry the transaction's
|
|
218
|
+
* token, so the gate admits them while the transaction is open.
|
|
219
|
+
*/
|
|
220
|
+
private handleStatements;
|
|
221
|
+
/** Rolls back the open transaction; one that already ended (a failed statement, close()) is left alone. */
|
|
222
|
+
private rollbackQuietly;
|
|
223
|
+
/**
|
|
224
|
+
* Begins a transaction the caller ends with commit() or rollback(). It is not
|
|
225
|
+
* the callback form: other callers' statements are not held out of it.
|
|
185
226
|
*/
|
|
186
227
|
beginTransaction(): Promise<void>;
|
|
187
228
|
/**
|
|
@@ -193,18 +234,27 @@ export declare class IndexedDbAdapter implements StorageAdapter {
|
|
|
193
234
|
*/
|
|
194
235
|
rollback(): Promise<void>;
|
|
195
236
|
/**
|
|
196
|
-
* Closes the database and
|
|
237
|
+
* Closes the database and saves its committed state to IndexedDB.
|
|
238
|
+
*
|
|
239
|
+
* A transaction still open is rolled back, as closing a SQLite connection
|
|
240
|
+
* does, before the save; the save then holds committed writes only. A call
|
|
241
|
+
* made while a close is running waits for that close.
|
|
197
242
|
*/
|
|
198
243
|
close(): Promise<void>;
|
|
244
|
+
private closeNow;
|
|
199
245
|
/**
|
|
200
246
|
* Exports the database as a Uint8Array (SQLite file format).
|
|
201
247
|
* Can be downloaded or stored externally.
|
|
248
|
+
*
|
|
249
|
+
* Throws while a transaction is open: sql.js's export closes and reopens the
|
|
250
|
+
* connection, which would end the transaction.
|
|
202
251
|
* @returns SQLite database file as binary
|
|
203
252
|
*/
|
|
204
253
|
exportDatabase(): Uint8Array;
|
|
205
254
|
/**
|
|
206
255
|
* Imports a database from a Uint8Array (SQLite file).
|
|
207
|
-
* Replaces the current database
|
|
256
|
+
* Replaces the current database once any open transaction() has ended, and
|
|
257
|
+
* saves it to IndexedDB before it resolves.
|
|
208
258
|
* @param data SQLite database file
|
|
209
259
|
*/
|
|
210
260
|
importDatabase(data: Uint8Array): Promise<void>;
|
|
@@ -231,22 +281,51 @@ export declare class IndexedDbAdapter implements StorageAdapter {
|
|
|
231
281
|
*/
|
|
232
282
|
private loadFromIndexedDb;
|
|
233
283
|
/**
|
|
234
|
-
*
|
|
284
|
+
* Writes the current image to IndexedDB. Never called while a transaction is
|
|
285
|
+
* open (see saveIfIdle): sql.js's export() closes and reopens the connection,
|
|
286
|
+
* which ends an open transaction.
|
|
287
|
+
*
|
|
288
|
+
* Settles when the IndexedDB transaction completes, not when its put request
|
|
289
|
+
* succeeds: the transaction can still abort after that (a quota error at
|
|
290
|
+
* commit), and the image is then not stored. On abort the writes stay
|
|
291
|
+
* unsaved, so the next save writes them. A write made after the export stays
|
|
292
|
+
* unsaved too.
|
|
235
293
|
*/
|
|
236
294
|
private saveToIndexedDb;
|
|
295
|
+
/** Whether writes were made since the image the last completed save exported. */
|
|
296
|
+
private hasUnsavedWrites;
|
|
297
|
+
/**
|
|
298
|
+
* Whether a transaction is open on the connection: one transaction() is
|
|
299
|
+
* running, or one the caller began with BEGIN or SAVEPOINT. sql.js does not
|
|
300
|
+
* export sqlite3_get_autocommit, so the adapter asks SQLite: BEGIN fails
|
|
301
|
+
* inside a transaction, and outside one it is rolled back at once. A probe
|
|
302
|
+
* that fails for any reason counts as open, so the adapter does not export.
|
|
303
|
+
*/
|
|
304
|
+
private inTransaction;
|
|
305
|
+
/**
|
|
306
|
+
* Starts a save of the unsaved writes, unless a save is running or a
|
|
307
|
+
* transaction is open; the auto-save tick tries again later.
|
|
308
|
+
*/
|
|
309
|
+
private saveIfIdle;
|
|
310
|
+
/**
|
|
311
|
+
* Starts a save at once and keeps it as the save in progress. The caller has
|
|
312
|
+
* made sure no transaction is open: the export would end it.
|
|
313
|
+
*/
|
|
314
|
+
private startSave;
|
|
315
|
+
/** Waits for a save in progress to settle, whether it succeeded or not. */
|
|
316
|
+
private settleSave;
|
|
317
|
+
private reportLongWait;
|
|
237
318
|
/**
|
|
238
319
|
* Wraps a transaction operation with retry logic.
|
|
239
320
|
* Handles "NotFoundError" by reopening IndexedDB connection.
|
|
240
321
|
*/
|
|
241
322
|
private withTransactionRetry;
|
|
242
|
-
/**
|
|
243
|
-
* Persists to IndexedDB if auto-save is enabled.
|
|
244
|
-
*/
|
|
245
|
-
private persistIfNeeded;
|
|
246
323
|
/**
|
|
247
324
|
* Starts auto-save interval.
|
|
248
325
|
*/
|
|
249
326
|
private startAutoSave;
|
|
327
|
+
/** One auto-save tick: a failed save is reported once and tried again on the next tick. */
|
|
328
|
+
private autoSaveTick;
|
|
250
329
|
/**
|
|
251
330
|
* Ensures the database is open.
|
|
252
331
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"indexedDbAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/indexedDbAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAIH,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"indexedDbAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/indexedDbAdapter.ts"],"names":[],"mappings":"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"}
|