@framers/sql-storage-adapter 0.6.15 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/README.md +174 -3
  2. package/dist/adapters/baseStorageAdapter.d.ts.map +1 -1
  3. package/dist/adapters/baseStorageAdapter.js +4 -2
  4. package/dist/adapters/baseStorageAdapter.js.map +1 -1
  5. package/dist/adapters/betterSqliteAdapter.d.ts +18 -2
  6. package/dist/adapters/betterSqliteAdapter.d.ts.map +1 -1
  7. package/dist/adapters/betterSqliteAdapter.js +23 -7
  8. package/dist/adapters/betterSqliteAdapter.js.map +1 -1
  9. package/dist/adapters/capacitorSqliteAdapter.d.ts +8 -0
  10. package/dist/adapters/capacitorSqliteAdapter.d.ts.map +1 -1
  11. package/dist/adapters/capacitorSqliteAdapter.js +11 -1
  12. package/dist/adapters/capacitorSqliteAdapter.js.map +1 -1
  13. package/dist/adapters/electron/electronMainAdapter.d.ts +10 -0
  14. package/dist/adapters/electron/electronMainAdapter.d.ts.map +1 -1
  15. package/dist/adapters/electron/electronMainAdapter.js +21 -12
  16. package/dist/adapters/electron/electronMainAdapter.js.map +1 -1
  17. package/dist/adapters/indexedDbAdapter.d.ts +202 -54
  18. package/dist/adapters/indexedDbAdapter.d.ts.map +1 -1
  19. package/dist/adapters/indexedDbAdapter.js +560 -123
  20. package/dist/adapters/indexedDbAdapter.js.map +1 -1
  21. package/dist/adapters/postgresAdapter.d.ts +159 -3
  22. package/dist/adapters/postgresAdapter.d.ts.map +1 -1
  23. package/dist/adapters/postgresAdapter.js +667 -140
  24. package/dist/adapters/postgresAdapter.js.map +1 -1
  25. package/dist/adapters/sqlJsAdapter.d.ts +21 -3
  26. package/dist/adapters/sqlJsAdapter.d.ts.map +1 -1
  27. package/dist/adapters/sqlJsAdapter.js +29 -26
  28. package/dist/adapters/sqlJsAdapter.js.map +1 -1
  29. package/dist/core/contracts/index.d.ts +9 -0
  30. package/dist/core/contracts/index.d.ts.map +1 -1
  31. package/dist/core/contracts/index.js.map +1 -1
  32. package/dist/core/database.d.ts +43 -8
  33. package/dist/core/database.d.ts.map +1 -1
  34. package/dist/core/database.js +40 -5
  35. package/dist/core/database.js.map +1 -1
  36. package/dist/core/resolver.d.ts +20 -1
  37. package/dist/core/resolver.d.ts.map +1 -1
  38. package/dist/core/resolver.js +33 -11
  39. package/dist/core/resolver.js.map +1 -1
  40. package/dist/features/kv/idb.d.ts +79 -0
  41. package/dist/features/kv/idb.d.ts.map +1 -0
  42. package/dist/features/kv/idb.js +14 -0
  43. package/dist/features/kv/idb.js.map +1 -0
  44. package/dist/features/kv/index.d.ts +14 -0
  45. package/dist/features/kv/index.d.ts.map +1 -0
  46. package/dist/features/kv/index.js +14 -0
  47. package/dist/features/kv/index.js.map +1 -0
  48. package/dist/features/kv/indexedDbKeyValueStore.d.ts +77 -0
  49. package/dist/features/kv/indexedDbKeyValueStore.d.ts.map +1 -0
  50. package/dist/features/kv/indexedDbKeyValueStore.js +127 -0
  51. package/dist/features/kv/indexedDbKeyValueStore.js.map +1 -0
  52. package/dist/features/kv/keyValueStore.d.ts +48 -0
  53. package/dist/features/kv/keyValueStore.d.ts.map +1 -0
  54. package/dist/features/kv/keyValueStore.js +54 -0
  55. package/dist/features/kv/keyValueStore.js.map +1 -0
  56. package/dist/features/kv/sqlKeyValueStore.d.ts +34 -0
  57. package/dist/features/kv/sqlKeyValueStore.d.ts.map +1 -0
  58. package/dist/features/kv/sqlKeyValueStore.js +91 -0
  59. package/dist/features/kv/sqlKeyValueStore.js.map +1 -0
  60. package/dist/features/kv/valueCodec.d.ts +35 -0
  61. package/dist/features/kv/valueCodec.d.ts.map +1 -0
  62. package/dist/features/kv/valueCodec.js +462 -0
  63. package/dist/features/kv/valueCodec.js.map +1 -0
  64. package/dist/features/migrations/dataExport.js +9 -6
  65. package/dist/features/migrations/dataExport.js.map +1 -1
  66. package/dist/index.d.ts +3 -0
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +5 -0
  69. package/dist/index.js.map +1 -1
  70. package/dist/shared/errors.d.ts +23 -0
  71. package/dist/shared/errors.d.ts.map +1 -0
  72. package/dist/shared/errors.js +44 -0
  73. package/dist/shared/errors.js.map +1 -0
  74. package/dist/shared/logger.d.ts +26 -0
  75. package/dist/shared/logger.d.ts.map +1 -0
  76. package/dist/shared/logger.js +26 -0
  77. package/dist/shared/logger.js.map +1 -0
  78. package/dist/shared/parameterUtils.d.ts +7 -0
  79. package/dist/shared/parameterUtils.d.ts.map +1 -1
  80. package/dist/shared/parameterUtils.js +25 -0
  81. package/dist/shared/parameterUtils.js.map +1 -1
  82. package/dist/shared/postgresTarget.d.ts +4 -3
  83. package/dist/shared/postgresTarget.d.ts.map +1 -1
  84. package/dist/shared/postgresTarget.js +6 -4
  85. package/dist/shared/postgresTarget.js.map +1 -1
  86. package/dist/shared/segment.d.ts +43 -0
  87. package/dist/shared/segment.d.ts.map +1 -0
  88. package/dist/shared/segment.js +77 -0
  89. package/dist/shared/segment.js.map +1 -0
  90. package/dist/shared/sqlPlaceholders.d.ts +40 -0
  91. package/dist/shared/sqlPlaceholders.d.ts.map +1 -0
  92. package/dist/shared/sqlPlaceholders.js +276 -0
  93. package/dist/shared/sqlPlaceholders.js.map +1 -0
  94. package/package.json +10 -2
@@ -26,12 +26,12 @@
26
26
  *
27
27
  * @example
28
28
  * ```typescript
29
- * import { IndexedDbAdapter } from '@framers/sql-storage-adapter/adapters/indexedDbAdapter';
29
+ * import { IndexedDbAdapter } from '@framers/sql-storage-adapter';
30
30
  *
31
31
  * const adapter = new IndexedDbAdapter({
32
32
  * dbName: 'my-app-db',
33
- * autoSave: true,
34
- * saveIntervalMs: 5000,
33
+ * durability: 'commit', // each write is in IndexedDB before it resolves
34
+ * crossTab: true, // two tabs of the site keep each other's writes
35
35
  * });
36
36
  *
37
37
  * await adapter.open();
@@ -43,6 +43,27 @@
43
43
  * ```
44
44
  */
45
45
  import type { StorageAdapter, StorageCapability, StorageOpenOptions, StorageParameters, StorageRunResult } from '../core/contracts/index.js';
46
+ /**
47
+ * The part of the Web Locks API (`navigator.locks`) the adapter uses: an
48
+ * exclusive lock per name, granted to one holder at a time, in the order
49
+ * asked, and held until the callback's promise settles.
50
+ */
51
+ export interface IndexedDbLockManager {
52
+ request<T>(name: string, options: {
53
+ mode: 'exclusive';
54
+ }, callback: () => Promise<T>): Promise<T>;
55
+ }
56
+ /** How tabs coordinate their saves. */
57
+ export interface IndexedDbCrossTabOptions {
58
+ /**
59
+ * The lock manager: the browser's `navigator.locks` when left out. `null`
60
+ * coordinates by the version stamp alone, as the adapter does where the
61
+ * browser has no Web Locks.
62
+ */
63
+ locks?: IndexedDbLockManager | null;
64
+ }
65
+ /** When a write is stored in IndexedDB. */
66
+ export type IndexedDbDurability = 'interval' | 'commit';
46
67
  /**
47
68
  * Configuration for IndexedDB adapter.
48
69
  */
@@ -51,12 +72,63 @@ export interface IndexedDbAdapterOptions {
51
72
  dbName?: string;
52
73
  /** IndexedDB object store name (default: 'sqliteDb') */
53
74
  storeName?: string;
54
- /** Auto-save to IndexedDB after each write (default: true) */
75
+ /** Auto-save to IndexedDB on a timer (default: true) */
55
76
  autoSave?: boolean;
56
77
  /** Save interval in milliseconds for batched writes (default: 5000) */
57
78
  saveIntervalMs?: number;
58
79
  /** sql.js configuration (e.g., locateFile for wasm) */
59
80
  sqlJsConfig?: any;
81
+ /**
82
+ * When a write is stored in IndexedDB.
83
+ *
84
+ * - `'interval'`, the default: the auto-save tick stores the writes made
85
+ * since the last save, every `saveIntervalMs`; `flush()` and `close()`
86
+ * store them at once. A write can be lost when the page goes before the
87
+ * next tick.
88
+ * - `'commit'`: `run()`, `exec()`, a write through `all()` or `get()`
89
+ * (`INSERT ... RETURNING`) and `transaction()` resolve once their write is
90
+ * in IndexedDB, and reject when IndexedDB refuses it (the write stays in
91
+ * the database and the next save stores it). Each save writes the whole
92
+ * database image, so batch many writes in one `transaction()`. While a
93
+ * transaction a caller opened with `BEGIN` is open, nothing can be saved:
94
+ * its statements resolve at once, and its rows are stored when its
95
+ * `COMMIT` resolves.
96
+ */
97
+ durability?: IndexedDbDurability;
98
+ /**
99
+ * Keeps the writes of two tabs of the site that open the same database.
100
+ * Each tab holds the whole database in memory and writes it back whole, so
101
+ * without this the tab that saves last overwrites the other's writes.
102
+ *
103
+ * With `crossTab`, every statement and transaction runs under a Web Lock on
104
+ * the database, on the newest stored image (a tab reloads it when another
105
+ * has saved), and is stored before the lock is let go: `durability` is
106
+ * `'commit'` whatever it says. Where the browser has no Web Locks (Safari
107
+ * before 15.4, an insecure origin, Lockdown Mode), the version stamp stored
108
+ * beside the image keeps both tabs' writes alone: a statement that finds
109
+ * another tab saved first runs again on the newer image, and a
110
+ * `transaction()` is refused with `IndexedDbConflictError`, storing
111
+ * nothing, for its caller to run again. The adapter says once when it runs
112
+ * without Web Locks.
113
+ *
114
+ * A transaction begun with `BEGIN` through `run()` or `exec()` cannot be
115
+ * held across tabs: it is rolled back and refused. Use `transaction()`.
116
+ */
117
+ crossTab?: boolean | IndexedDbCrossTabOptions;
118
+ /**
119
+ * A database of its own: the segment is appended to `dbName`
120
+ * (`app-db` becomes `app-db-agentos`). Lower-case letters, digits and
121
+ * underscores.
122
+ */
123
+ segment?: string;
124
+ }
125
+ /**
126
+ * A `transaction()` another tab saved over: refused, with nothing of it
127
+ * stored. The adapter has loaded the other tab's image, so running the
128
+ * transaction again keeps both tabs' writes.
129
+ */
130
+ export declare class IndexedDbConflictError extends Error {
131
+ constructor(message: string);
60
132
  }
61
133
  /**
62
134
  * Storage adapter using IndexedDB + sql.js for client-side SQL persistence.
@@ -75,51 +147,21 @@ export interface IndexedDbAdapterOptions {
75
147
  * - Auto-save batching reduces overhead
76
148
  * - Good for: Production PWAs, offline-first apps, persistent client-side storage
77
149
  *
78
- * **Is This Necessary?**
79
- *
80
- * **✅ YES** if you need:
81
- * - Data to survive page refreshes (production apps)
82
- * - Offline-first functionality (PWAs)
83
- * - Privacy-first apps (data never leaves browser)
84
- * - Zero manual save logic (just works)
85
- *
86
- * **❌ NO** if you:
87
- * - Only need temporary/in-memory data (edge functions)
88
- * - Are prototyping and don't care about persistence
89
- * - Want to manually control when data is saved
90
- * - Don't need data to survive refreshes
91
- *
92
- * **Alternative:** You could use sql.js directly and manually save to IndexedDB yourself, but you'd lose:
93
- * - Automatic batched saves (performance optimization)
94
- * - Reliable persistence (easy to forget manual saves = data loss)
95
- * - Consistent API across platforms
96
- * - Production-ready defaults
97
- *
98
- * **Bottom line:** This adapter is **necessary for production web apps** that need persistence. For prototypes or edge functions, sql.js alone is fine.
99
- *
100
150
  * **How It Works:**
101
151
  * 1. IndexedDB stores the SQLite database file (binary blob) - this is just storage
102
152
  * 2. sql.js (WASM) loads the database into memory and executes SQL - this provides SQL capabilities
103
- * 3. After writes, the updated database is automatically saved back to IndexedDB
104
- *
105
- * **Why IndexedDB + sql.js?**
106
- * - IndexedDB alone: NoSQL key-value store, no SQL support
107
- * - sql.js alone: In-memory SQL, but **no automatic persistence** (you must manually save)
108
- * - Combined: Full SQL + **automatic browser-native persistence** = production-ready solution
153
+ * 3. After writes, the updated database is saved back to IndexedDB: on a timer
154
+ * (the default), before each write resolves (`durability: 'commit'`), or
155
+ * under a cross-tab lock (`crossTab`)
109
156
  *
110
157
  * **Capabilities:**
111
158
  * - ✅ Transactions (via sql.js)
112
159
  * - ✅ Persistence (via IndexedDB - automatic!)
113
160
  * - ✅ Full SQL support (via sql.js)
114
161
  * - ✅ Export/import
115
- * - ❌ Concurrent writes (single-threaded)
162
+ * - ✅ Several tabs on one database, with `crossTab`
116
163
  * - ❌ Server-side (browser only)
117
164
  *
118
- * **Performance:**
119
- * - Fast reads (in-memory SQL)
120
- * - Moderate writes (IndexedDB persistence)
121
- * - Auto-save batching reduces IDB overhead
122
- *
123
165
  * @example Client-side application
124
166
  * ```typescript
125
167
  * const adapter = new IndexedDbAdapter({ dbName: 'my-app-db' });
@@ -132,6 +174,8 @@ export declare class IndexedDbAdapter implements StorageAdapter {
132
174
  readonly capabilities: ReadonlySet<StorageCapability>;
133
175
  private SQL;
134
176
  private db;
177
+ /** Foreign-key enforcement as open() was asked for it (undefined: the engine default); sql.js forgets the PRAGMA when export() reopens the connection. */
178
+ private foreignKeys;
135
179
  private idb;
136
180
  private saveTimer;
137
181
  /** Bumped by every statement that can change the database. */
@@ -140,13 +184,31 @@ export declare class IndexedDbAdapter implements StorageAdapter {
140
184
  private savedGeneration;
141
185
  /** The save in progress, if any. */
142
186
  private saving;
187
+ /** The generation the save in progress exported. */
188
+ private savingGeneration;
143
189
  /** Whether a failed auto-save has been reported since the last one that succeeded. */
144
190
  private saveFailureReported;
191
+ /** The open() in progress, which a second call waits for. */
192
+ private opening;
145
193
  /** Set while close() runs: no statement or transaction starts. */
146
194
  private closing;
147
195
  /** The close() in progress, which a second call waits for. */
148
196
  private closeRun;
149
197
  private longWaitReported;
198
+ private lockWaitReported;
199
+ /** The stamp of the image the database in memory was loaded from or last saved as. */
200
+ private loadedStamp;
201
+ /** How many stamps this adapter has made, which keeps two of its stamps apart. */
202
+ private stampCount;
203
+ /** The connection settings a fresh connection has, which a save need not set again. */
204
+ private pragmaDefaults;
205
+ /**
206
+ * With `crossTab`, the lock manager, or null for the version stamp alone;
207
+ * undefined without `crossTab`.
208
+ */
209
+ private locks;
210
+ /** Without Web Locks, this adapter's coordinated operations run one at a time. */
211
+ private readonly runCoordinatedInTurn;
150
212
  /**
151
213
  * The connection is shared, so transaction() runs one callback at a time.
152
214
  */
@@ -164,17 +226,25 @@ export declare class IndexedDbAdapter implements StorageAdapter {
164
226
  private readonly storeName;
165
227
  private readonly autoSave;
166
228
  private readonly saveIntervalMs;
229
+ private readonly durability;
230
+ private readonly crossTab;
167
231
  private readonly sqlJsConfig;
232
+ /** @throws {Error} When `options.segment` is not a name a segment can take. */
168
233
  constructor(options?: IndexedDbAdapterOptions);
234
+ /** The name of the Web Lock that coordinates the tabs on this database. */
235
+ private get lockName();
169
236
  /**
170
237
  * Opens IndexedDB and initializes sql.js database.
171
238
  * Loads existing database from IndexedDB if present.
172
239
  *
173
240
  * Uses a global sql.js singleton to prevent race conditions when
174
241
  * multiple adapters (e.g., fabric_codex_db and quarry-codex-local)
175
- * are initialized simultaneously.
242
+ * are initialized simultaneously. Two calls at once open once.
176
243
  */
177
- open(_options?: StorageOpenOptions): Promise<void>;
244
+ open(options?: StorageOpenOptions): Promise<void>;
245
+ private openNow;
246
+ /** The lock manager crossTab uses, or null for the version stamp alone. */
247
+ private resolveLocks;
178
248
  /**
179
249
  * Executes a SQL statement that doesn't return rows (INSERT, UPDATE, DELETE, CREATE, etc.).
180
250
  * @param statement SQL statement with ? or :name placeholders
@@ -191,18 +261,26 @@ export declare class IndexedDbAdapter implements StorageAdapter {
191
261
  */
192
262
  get<T>(statement: string, parameters?: StorageParameters): Promise<T | null>;
193
263
  /**
194
- * Executes a SQL query and returns all matching rows.
264
+ * Executes a SQL query and returns all matching rows. A statement that
265
+ * writes (`INSERT ... RETURNING`) is saved like a `run()`.
195
266
  * @param statement SELECT statement
196
267
  * @param parameters Query parameters
197
268
  * @returns Array of result rows as objects
198
269
  */
199
270
  all<T>(statement: string, parameters?: StorageParameters): Promise<T[]>;
200
271
  private allNow;
272
+ /** The rows changed on this connection since it opened. */
273
+ private totalChanges;
201
274
  /**
202
275
  * Executes a script containing multiple SQL statements.
203
276
  */
204
277
  exec(script: string): Promise<void>;
205
278
  private execNow;
279
+ /**
280
+ * With `durability: 'commit'`, resolves with `result` once the write that
281
+ * produced it is stored; otherwise with `result` at once.
282
+ */
283
+ private stored;
206
284
  /**
207
285
  * Executes a callback within a database transaction.
208
286
  *
@@ -210,9 +288,12 @@ export declare class IndexedDbAdapter implements StorageAdapter {
210
288
  * connection. The callback's statements go through the handle it receives;
211
289
  * a statement issued through the adapter itself while the callback runs
212
290
  * 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.
291
+ * auto-save tick does not save while a transaction is open. With
292
+ * `durability: 'commit'` the transaction resolves once it is stored.
214
293
  */
215
294
  transaction<T>(fn: (trx: StorageAdapter) => Promise<T>): Promise<T>;
295
+ /** Runs one transaction: BEGIN, the callback through its handle, COMMIT or ROLLBACK. */
296
+ private transactionNow;
216
297
  /**
217
298
  * The statements of one transaction's handle: they carry the transaction's
218
299
  * token, so the gate admits them while the transaction is open.
@@ -222,7 +303,8 @@ export declare class IndexedDbAdapter implements StorageAdapter {
222
303
  private rollbackQuietly;
223
304
  /**
224
305
  * 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.
306
+ * the callback form: other callers' statements are not held out of it. With
307
+ * `crossTab` it is refused: use transaction().
226
308
  */
227
309
  beginTransaction(): Promise<void>;
228
310
  /**
@@ -233,6 +315,13 @@ export declare class IndexedDbAdapter implements StorageAdapter {
233
315
  * Rolls back the current transaction.
234
316
  */
235
317
  rollback(): Promise<void>;
318
+ /**
319
+ * Stores every write made so far in IndexedDB. A `transaction()` that is
320
+ * open is waited for and stored with the rest; a transaction a caller began
321
+ * with `BEGIN` cannot be stored without ending it, so flush() rejects while
322
+ * one is open. Resolves at once when nothing is waiting to be saved.
323
+ */
324
+ flush(): Promise<void>;
236
325
  /**
237
326
  * Closes the database and saves its committed state to IndexedDB.
238
327
  *
@@ -244,20 +333,74 @@ export declare class IndexedDbAdapter implements StorageAdapter {
244
333
  private closeNow;
245
334
  /**
246
335
  * Exports the database as a Uint8Array (SQLite file format).
247
- * Can be downloaded or stored externally.
336
+ * Can be downloaded or stored externally. With `crossTab` it is this tab's
337
+ * image, which another tab's save can have overtaken.
248
338
  *
249
339
  * Throws while a transaction is open: sql.js's export closes and reopens the
250
340
  * connection, which would end the transaction.
251
341
  * @returns SQLite database file as binary
252
342
  */
253
343
  exportDatabase(): Uint8Array;
344
+ /**
345
+ * Applies the connection settings open() was asked for. sql.js loses them
346
+ * whenever export() reopens the connection; a save, an export, an import
347
+ * and a reload set them again with the other settings a caller changed
348
+ * (exportImage, replaceDatabase).
349
+ */
350
+ private applyConnectionSettings;
254
351
  /**
255
352
  * Imports a database from a Uint8Array (SQLite file).
256
353
  * Replaces the current database once any open transaction() has ended, and
257
- * saves it to IndexedDB before it resolves.
354
+ * saves it to IndexedDB before it resolves; with `crossTab`, in place of
355
+ * what every tab stored. Bytes that are not a SQLite database are refused,
356
+ * and the adapter keeps its database.
258
357
  * @param data SQLite database file
259
358
  */
260
359
  importDatabase(data: Uint8Array): Promise<void>;
360
+ /** Replaces the database with an image, once sql.js has read it as a SQLite database. */
361
+ private swapIn;
362
+ /** Puts `next` in place of the database, with the connection settings the current one has. */
363
+ private replaceDatabase;
364
+ /**
365
+ * Runs `work` with this tab holding the database: under the Web Lock, or,
366
+ * without Web Locks, after this adapter's earlier coordinated work.
367
+ */
368
+ private withCoordination;
369
+ /**
370
+ * One statement across tabs: on the newest stored image, and stored before
371
+ * it resolves. Without Web Locks another tab can save between the load and
372
+ * the save; the statement then runs again on that tab's image.
373
+ */
374
+ private coordinatedStatement;
375
+ /**
376
+ * One transaction across tabs: on the newest stored image, and stored before
377
+ * it resolves. Without Web Locks another tab can save while the callback
378
+ * runs; the transaction is then refused, nothing of it is stored, and the
379
+ * other tab's image is loaded for the caller to run it again.
380
+ */
381
+ private coordinatedTransaction;
382
+ /** Loads the stored image when another tab (or adapter) has saved since this one loaded or saved. */
383
+ private syncFromStore;
384
+ /** Reads the stored stamp, and the image with it when the stamp is not `known`; null when it is. */
385
+ private readIfChanged;
386
+ /**
387
+ * Stores the image when the stored stamp is still `expected`, in one
388
+ * IndexedDB transaction, so no other tab's save lands between the check and
389
+ * the write. `undefined` stores it whatever the stamp is. Resolves with
390
+ * whether it stored the image.
391
+ */
392
+ private saveIfStampIs;
393
+ /** A stamp no other save of this or another tab writes. */
394
+ private nextStamp;
395
+ /**
396
+ * Exports the database for a save, keeping the connection settings a
397
+ * caller made: sql.js's export() closes the connection and opens it again.
398
+ */
399
+ private exportImage;
400
+ /** The connection settings that differ from a fresh connection's. */
401
+ private changedPragmas;
402
+ /** Sets connection settings on the database, after a save or a reload. */
403
+ private applyPragmas;
261
404
  /**
262
405
  * Opens or creates the IndexedDB database.
263
406
  */
@@ -276,14 +419,14 @@ export declare class IndexedDbAdapter implements StorageAdapter {
276
419
  */
277
420
  private openIndexedDbWithRetry;
278
421
  /**
279
- * Loads the SQLite database from IndexedDB.
280
- * @returns Binary database or null if not found
422
+ * Loads the SQLite database and its stamp from IndexedDB, in one
423
+ * transaction, so the two belong together.
281
424
  */
282
425
  private loadFromIndexedDb;
283
426
  /**
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.
427
+ * Writes the current image to IndexedDB, with a new stamp. Never called
428
+ * while a transaction is open (see saveIfIdle): sql.js's export() closes and
429
+ * reopens the connection, which ends an open transaction.
287
430
  *
288
431
  * Settles when the IndexedDB transaction completes, not when its put request
289
432
  * succeeds: the transaction can still abort after that (a quota error at
@@ -307,6 +450,14 @@ export declare class IndexedDbAdapter implements StorageAdapter {
307
450
  * transaction is open; the auto-save tick tries again later.
308
451
  */
309
452
  private saveIfIdle;
453
+ /**
454
+ * Resolves once the writes up to `generation` are stored. A save in
455
+ * progress that holds them is waited for; an open transaction() is waited
456
+ * for, since its own save holds them; while a transaction a caller began
457
+ * with BEGIN is open, nothing can be stored, and its COMMIT stores them.
458
+ * Rejects when the save that held them failed.
459
+ */
460
+ private saveThrough;
310
461
  /**
311
462
  * Starts a save at once and keeps it as the save in progress. The caller has
312
463
  * made sure no transaction is open: the export would end it.
@@ -315,6 +466,7 @@ export declare class IndexedDbAdapter implements StorageAdapter {
315
466
  /** Waits for a save in progress to settle, whether it succeeded or not. */
316
467
  private settleSave;
317
468
  private reportLongWait;
469
+ private reportLockWait;
318
470
  /**
319
471
  * Wraps a transaction operation with retry logic.
320
472
  * Handles "NotFoundError" by reopening IndexedDB connection.
@@ -334,9 +486,5 @@ export declare class IndexedDbAdapter implements StorageAdapter {
334
486
  * Normalizes last insert row ID to string or number.
335
487
  */
336
488
  private normaliseRowId;
337
- /**
338
- * Prepares a SQL statement for execution.
339
- */
340
- private prepareInternal;
341
489
  }
342
490
  //# sourceMappingURL=indexedDbAdapter.d.ts.map
@@ -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;AA0C3B;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,kDAAkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uDAAuD;IAEvD,WAAW,CAAC,EAAE,GAAG,CAAC;CACnB;AAID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AACH,qBAAa,gBAAiB,YAAW,cAAc;IACrD,SAAgB,IAAI,eAAe;IACnC,SAAgB,YAAY,EAAE,WAAW,CAAC,iBAAiB,CAAC,CAAgE;IAE5H,OAAO,CAAC,GAAG,CAA4B;IACvC,OAAO,CAAC,EAAE,CAA8B;IACxC,OAAO,CAAC,GAAG,CAA4B;IACvC,OAAO,CAAC,SAAS,CAA+C;IAChE,8DAA8D;IAC9D,OAAO,CAAC,eAAe,CAAK;IAC5B,wFAAwF;IACxF,OAAO,CAAC,eAAe,CAAK;IAC5B,oCAAoC;IACpC,OAAO,CAAC,MAAM,CAA8B;IAC5C,sFAAsF;IACtF,OAAO,CAAC,mBAAmB,CAAS;IACpC,kEAAkE;IAClE,OAAO,CAAC,OAAO,CAAS;IACxB,8DAA8D;IAC9D,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,gBAAgB,CAAS;IACjC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAuC;IAChF;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA0D;IAC/E,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAGvB;IAEF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAM;gBAEtB,OAAO,GAAE,uBAA4B;IAQjD;;;;;;;OAOG;IACU,IAAI,CAAC,QAAQ,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB/D;;;;;OAKG;IACU,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAI9F,OAAO,CAAC,MAAM;IA0Bd;;;;;OAKG;IACU,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAKzF;;;;;OAKG;IACU,GAAG,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC;IAIpF,OAAO,CAAC,MAAM;IA8Bd;;OAEG;IACU,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhD,OAAO,CAAC,OAAO;IAUf;;;;;;;;OAQG;IACU,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IA2BhF;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAmBxB,2GAA2G;IAC3G,OAAO,CAAC,eAAe;IASvB;;;OAGG;IACU,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9C;;OAEG;IACU,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAIpC;;OAEG;IACU,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAItC;;;;;;OAMG;IACI,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YASf,QAAQ;IAgCtB;;;;;;;OAOG;IACI,cAAc,IAAI,UAAU;IAUnC;;;;;OAKG;IACU,cAAc,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB5D;;OAEG;IACH,OAAO,CAAC,aAAa;IAgBrB;;;;;;;;;;;OAWG;YACW,sBAAsB;IAiCpC;;;OAGG;YACW,iBAAiB;IAe/B;;;;;;;;;;OAUG;YACW,eAAe;IAoB7B,iFAAiF;IACjF,OAAO,CAAC,gBAAgB;IAIxB;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAiBrB;;;OAGG;IACH,OAAO,CAAC,UAAU;IAQlB;;;OAGG;IACH,OAAO,CAAC,SAAS;IAQjB,2EAA2E;YAC7D,UAAU;IAMxB,OAAO,CAAC,cAAc;IAUtB;;;OAGG;YACW,oBAAoB;IAyClC;;OAEG;IACH,OAAO,CAAC,aAAa;IAMrB,2FAA2F;YAC7E,YAAY;IAY1B;;OAEG;IACH,OAAO,CAAC,UAAU;IAMlB;;OAEG;IACH,OAAO,CAAC,cAAc;IAUtB;;OAEG;IACH,OAAO,CAAC,eAAe;CAIxB"}
1
+ {"version":3,"file":"indexedDbAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/indexedDbAdapter.ts"],"names":[],"mappings":"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"}