@delali/sirannon-db 0.3.5 → 0.3.6-next.78
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/dist/backup/index.d.ts +5 -5
- package/dist/backup/index.mjs +5 -3
- package/dist/backup-scheduler/index.d.ts +2 -2
- package/dist/backup-scheduler/index.mjs +2 -2
- package/dist/chunk-22TYGH7J.mjs +55 -0
- package/dist/{chunk-SB3MIFLG.mjs → chunk-2ZQOZFX7.mjs} +29 -6
- package/dist/{chunk-UIDQGPJY.mjs → chunk-4O7WYZHN.mjs} +38 -3
- package/dist/{chunk-ZFFUVYYE.mjs → chunk-5DKWHT6K.mjs} +109 -1
- package/dist/chunk-5O4J6LQQ.mjs +35 -0
- package/dist/{chunk-CZL4D3BM.mjs → chunk-6CABU54O.mjs} +2 -2
- package/dist/{chunk-JAQ2I4OT.mjs → chunk-A5ULJVK7.mjs} +11 -11
- package/dist/{chunk-RLBKZZ24.mjs → chunk-AC7TKWNH.mjs} +1 -0
- package/dist/chunk-BKO4SCEC.mjs +99 -0
- package/dist/{chunk-KOTBP4AW.mjs → chunk-C7E4H6UN.mjs} +24 -4
- package/dist/{chunk-G4AG3ESO.mjs → chunk-FBA7P4ZA.mjs} +114 -149
- package/dist/{chunk-DKML5425.mjs → chunk-GBVB6WSC.mjs} +2 -2
- package/dist/chunk-I4JY5QPA.mjs +51 -0
- package/dist/{chunk-L6EX6K27.mjs → chunk-MO4APBYG.mjs} +54 -13
- package/dist/{chunk-RPWBYASV.mjs → chunk-MTOQ6QIS.mjs} +1 -1
- package/dist/chunk-MX77PGEN.mjs +60 -0
- package/dist/{chunk-BTUD6XQO.mjs → chunk-N3MHZV3B.mjs} +11 -29
- package/dist/{chunk-UHUDPQFI.mjs → chunk-OJXV4L3N.mjs} +1 -3
- package/dist/chunk-QF7WF7RJ.mjs +34 -0
- package/dist/chunk-RLBV4YTB.mjs +22 -0
- package/dist/{chunk-ISDT4RBD.mjs → chunk-ULUZUBON.mjs} +1 -1
- package/dist/{chunk-AP4367HK.mjs → chunk-VGRAAQX3.mjs} +4 -4
- package/dist/chunk-W74HFQFD.mjs +153 -0
- package/dist/chunk-Y4SP7CRF.mjs +9 -0
- package/dist/{chunk-JFVEGN7J.mjs → chunk-ZAUHAJ4G.mjs} +2 -1
- package/dist/{chunk-DDIHBUEN.mjs → chunk-ZWW53O5P.mjs} +19 -7
- package/dist/client/index.d.ts +8 -8
- package/dist/client/topology.d.ts +4 -4
- package/dist/{client-base-Doaqwrx3.d.ts → client-base-DJZbSY55.d.ts} +2 -2
- package/dist/{client-streams-MKPE4MXW.mjs → client-streams-F7IG3PTU.mjs} +13 -16
- package/dist/core/index.d.ts +48 -12
- package/dist/core/index.mjs +1812 -107
- package/dist/core/writer-worker.mjs +28 -4
- package/dist/{database-fz-8CJBP.d.ts → database-BZ96ZzAx.d.ts} +411 -184
- package/dist/{database-backup-BwTNiBm2.d.ts → database-backup-BhM8yJ1A.d.ts} +32 -2
- package/dist/driver/better-sqlite3.d.ts +11 -1
- package/dist/driver/better-sqlite3.mjs +212 -23
- package/dist/driver/bun.d.ts +1 -1
- package/dist/driver/bun.mjs +15 -22
- package/dist/driver/expo.d.ts +1 -1
- package/dist/driver/expo.mjs +185 -16
- package/dist/driver/node.d.ts +1 -1
- package/dist/driver/node.mjs +15 -62
- package/dist/driver/wa-sqlite.d.ts +1 -1
- package/dist/driver/wa-sqlite.mjs +14 -153
- package/dist/{change-tracker-Dpo99EI-.d.ts → errors-DLMAGQFb.d.ts} +200 -2
- package/dist/file-migrations/index.d.ts +1 -1
- package/dist/peer-refusal-RR37UOLV.mjs +1 -0
- package/dist/{protocol-DZSYSv0S.d.ts → protocol-DE10taas.d.ts} +1 -1
- package/dist/replication/coordinator/etcd.mjs +1 -1
- package/dist/replication/index.d.ts +7 -7
- package/dist/replication/index.mjs +66 -9
- package/dist/{restore-options-CcMukOLO.d.ts → restore-options-B6HV_5XT.d.ts} +6 -1
- package/dist/server/index.d.ts +10 -10
- package/dist/server/index.mjs +506 -350
- package/dist/{server-options-B9CsAZp5.d.ts → server-options-Bhdlvehe.d.ts} +14 -1
- package/dist/{server-streams-SBYCHWWM.mjs → server-streams-Q2AZAW3N.mjs} +6 -30
- package/dist/{sirannon-D0CjDULa.d.ts → sirannon-Ba1o2HUQ.d.ts} +5 -5
- package/dist/transport/grpc.d.ts +15 -4
- package/dist/transport/grpc.mjs +34 -37
- package/dist/transport/memory.d.ts +4 -3
- package/dist/transport/memory.mjs +8 -26
- package/dist/{types-DTmi7pXp.d.ts → types-BWyv_N18.d.ts} +189 -1
- package/dist/{types-BlZ9GG1a.d.ts → types-CDnlkVRK.d.ts} +8 -2
- package/package.json +17 -9
- package/dist/chunk-DBN57KVR.mjs +0 -171
- package/dist/chunk-W67A4H2E.mjs +0 -23
- package/dist/chunk-YW7IKQ7T.mjs +0 -62
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { C as ChangeTracker, P as PruneBoundarySource } from './
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { C as ChangeTracker, S as SirannonError, P as PruneBoundarySource } from './errors-DLMAGQFb.js';
|
|
2
|
+
import { J as EncryptionKey, S as SQLiteDriver, X as SynchronousLevel, aw as WorkerHostOptions, L as SQLiteConnection, ax as ChangeDispatchObserver, ay as SubscriptionManager, az as WriterTransactionRunner, T as Transaction, aA as StatementMeter, aB as WriterContext, M as Migration, Z as MigrationResult, _ as RollbackResult, ar as QueryHookContext, a7 as ConnectionHookContext, a4 as BeforeSubscribeHook, a3 as BeforeSnapshotHook, a2 as BeforePushHook, ah as HookConfig, b as MetricsCollector, aC as QueryOutcomeMeasure, aD as QueryFailureMeasure, aE as QueryOutcome, aF as RowCounts, aq as OpenOptions, ag as EncryptionStatus, ae as EncryptionChange, D as DatabaseOptions, q as BackupFileReport, z as BackupToDestinationOptions, g as BackupRunReport, R as BackupScheduleOptions, h as BackupChain, p as BackupCycleStatus, C as BackupVerifyResult, l as BackupChainRecord, c as BeforeQueryHook, A as AfterQueryHook } from './types-BWyv_N18.js';
|
|
3
|
+
import { D as DatabaseBackupController, B as BackupCapabilities, a as BackupChainLocation, b as BackupRestorePlan, c as BackupSafeToDeleteOptions } from './database-backup-BhM8yJ1A.js';
|
|
4
4
|
import { H as HLCTimestamp, c as ReplicationChange, C as ConflictResolver, A as ApplyResult, R as ReplicationBatch } from './types-BG31TtrQ.js';
|
|
5
5
|
import { c as SubscriptionBuilder, P as Params, Q as QueryOptions, E as ExecuteResult, C as ChangeEvent } from './query-types-5B02ixH0.js';
|
|
6
|
-
import { A as AppliedMigrationRow, c as BulkLoadOptions, a as BulkLoadResult } from './server-options-
|
|
6
|
+
import { A as AppliedMigrationRow, c as BulkLoadOptions, a as BulkLoadResult } from './server-options-Bhdlvehe.js';
|
|
7
7
|
import { L as LiveQueryOptions, a as LiveQuery } from './types-CEJG0eFS.js';
|
|
8
8
|
|
|
9
9
|
interface DeviceRetentionPolicy {
|
|
@@ -19,201 +19,69 @@ interface ChangeRetentionOptions extends DeviceRetentionOptions {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
-
*
|
|
23
|
-
* {@link SirannonError.code}. Extend it to define an error of your own.
|
|
22
|
+
* A function that returns a database key, such as {@link EncryptionOptions.key}.
|
|
24
23
|
*
|
|
25
|
-
* @
|
|
26
|
-
*/
|
|
27
|
-
declare class SirannonError extends Error {
|
|
28
|
-
/**
|
|
29
|
-
* The machine-readable code that the server maps to an HTTP status.
|
|
30
|
-
*/
|
|
31
|
-
readonly code: string;
|
|
32
|
-
constructor(message: string,
|
|
33
|
-
/**
|
|
34
|
-
* The machine-readable code that the server maps to an HTTP status.
|
|
35
|
-
*/
|
|
36
|
-
code: string);
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Thrown when the registry has no open database under an identifier, because
|
|
40
|
-
* the database was never opened or is already closed.
|
|
41
|
-
*
|
|
42
|
-
* @public
|
|
43
|
-
*/
|
|
44
|
-
declare class DatabaseNotFoundError extends SirannonError {
|
|
45
|
-
constructor(id: string);
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Thrown when a caller opens a database under an identifier that the registry
|
|
49
|
-
* already uses, since each identifier names one database.
|
|
50
|
-
*
|
|
51
|
-
* @public
|
|
52
|
-
*/
|
|
53
|
-
declare class DatabaseAlreadyExistsError extends SirannonError {
|
|
54
|
-
constructor(id: string);
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Thrown when a caller writes to a database that is open in read-only mode.
|
|
58
|
-
*
|
|
59
|
-
* @public
|
|
60
|
-
*/
|
|
61
|
-
declare class ReadOnlyError extends SirannonError {
|
|
62
|
-
constructor(id: string);
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Thrown when SQLite fails to execute a statement, with that statement in
|
|
66
|
-
* {@link QueryError.sql} for your logs.
|
|
67
|
-
*
|
|
68
|
-
* @public
|
|
69
|
-
*/
|
|
70
|
-
declare class QueryError extends SirannonError {
|
|
71
|
-
/**
|
|
72
|
-
* The statement that failed.
|
|
73
|
-
*/
|
|
74
|
-
readonly sql: string;
|
|
75
|
-
constructor(message: string,
|
|
76
|
-
/**
|
|
77
|
-
* The statement that failed.
|
|
78
|
-
*/
|
|
79
|
-
sql: string);
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Sirannon raises this error when SQLite refuses to commit a transaction whose
|
|
83
|
-
* statements all succeeded, such as on a deferred foreign key; `cause` holds
|
|
84
|
-
* SQLite's own error. The server responds to its `TRANSACTION_ERROR` code with status 400.
|
|
85
|
-
*
|
|
86
|
-
* @public
|
|
87
|
-
*/
|
|
88
|
-
declare class TransactionError extends SirannonError {
|
|
89
|
-
constructor(message: string, cause?: unknown);
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Thrown when a migration fails, with the version of that migration in
|
|
93
|
-
* {@link MigrationError.version}.
|
|
94
|
-
*
|
|
95
|
-
* @public
|
|
96
|
-
*/
|
|
97
|
-
declare class MigrationError extends SirannonError {
|
|
98
|
-
/**
|
|
99
|
-
* The version of the migration that failed.
|
|
100
|
-
*/
|
|
101
|
-
readonly version: number;
|
|
102
|
-
constructor(message: string,
|
|
103
|
-
/**
|
|
104
|
-
* The version of the migration that failed.
|
|
105
|
-
*/
|
|
106
|
-
version: number, code?: string);
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* An error that a before-hook can throw to reject an operation, which the
|
|
110
|
-
* server responds to with status 403. The message includes the optional
|
|
111
|
-
* `reason`, so that a caller can tell one hook policy from another.
|
|
112
|
-
*
|
|
113
|
-
* @public
|
|
114
|
-
*/
|
|
115
|
-
declare class HookDeniedError extends SirannonError {
|
|
116
|
-
constructor(hookName: string, reason?: string);
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Rejects one request with a status of your own; throw it from an authenticate hook or a registered operation.
|
|
120
|
-
*
|
|
121
|
-
* @public
|
|
122
|
-
*/
|
|
123
|
-
declare class RequestDeniedError extends SirannonError {
|
|
124
|
-
/**
|
|
125
|
-
* The HTTP status that the server responds to the rejected request with.
|
|
126
|
-
*/
|
|
127
|
-
readonly status: number;
|
|
128
|
-
constructor(status: number, code: string, message: string);
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Thrown when change capture cannot proceed, for example when a caller watches
|
|
132
|
-
* a table that does not exist, when Sirannon cannot read the change-log epoch
|
|
133
|
-
* or the node identity, or when a live query uses a statement that Sirannon
|
|
134
|
-
* cannot keep current.
|
|
135
|
-
*
|
|
136
|
-
* @public
|
|
137
|
-
*/
|
|
138
|
-
declare class CDCError extends SirannonError {
|
|
139
|
-
constructor(message: string);
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Thrown when a statement through the query API names a `_sirannon` table,
|
|
143
|
-
* modifies a `sqlite_` table, contains ATTACH or DETACH, or sets
|
|
144
|
-
* `PRAGMA writable_schema`. Sirannon rejects these statements to keep its
|
|
145
|
-
* change log, its replication ledger, and SQLite's schema catalogue out of the
|
|
146
|
-
* caller's reach.
|
|
147
|
-
*
|
|
148
|
-
* @public
|
|
149
|
-
*/
|
|
150
|
-
declare class ForbiddenSqlError extends SirannonError {
|
|
151
|
-
constructor(message: string);
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Thrown when a copy to a file or a scheduled backup fails, or when its path,
|
|
155
|
-
* cron expression, or time zone is invalid.
|
|
156
|
-
*
|
|
157
|
-
* @public
|
|
24
|
+
* @internal
|
|
158
25
|
*/
|
|
159
|
-
|
|
160
|
-
constructor(message: string);
|
|
161
|
-
}
|
|
26
|
+
type EncryptionKeySource = () => EncryptionKey | Promise<EncryptionKey>;
|
|
162
27
|
/**
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
* fails to close.
|
|
28
|
+
* A key that Sirannon copied out of a key function's result, which the caller wipes once the connections that need it
|
|
29
|
+
* are open.
|
|
166
30
|
*
|
|
167
|
-
* @
|
|
31
|
+
* @internal
|
|
168
32
|
*/
|
|
169
|
-
|
|
170
|
-
|
|
33
|
+
interface ResolvedEncryptionKey {
|
|
34
|
+
/** A copy of the 32 key bytes that no other code holds. */
|
|
35
|
+
bytes: Uint8Array;
|
|
36
|
+
/** The identifier that came with the key. */
|
|
37
|
+
id?: string;
|
|
171
38
|
}
|
|
39
|
+
|
|
172
40
|
/**
|
|
173
|
-
*
|
|
174
|
-
* evicting the least recently used database frees no slot. Close a database
|
|
175
|
-
* before you open another one.
|
|
41
|
+
* The settings that an open passes to the driver for an encrypted database.
|
|
176
42
|
*
|
|
177
|
-
* @
|
|
43
|
+
* @internal
|
|
178
44
|
*/
|
|
179
|
-
|
|
180
|
-
|
|
45
|
+
interface KeyedOpenOptions {
|
|
46
|
+
encryption?: {
|
|
47
|
+
key: Uint8Array;
|
|
48
|
+
};
|
|
181
49
|
}
|
|
182
50
|
/**
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
* a `Retry-After` header.
|
|
51
|
+
* Holds the key function of one open database, and calls it each time the database opens connections, so that no key
|
|
52
|
+
* bytes stay in memory between opens.
|
|
186
53
|
*
|
|
187
|
-
* @
|
|
54
|
+
* @internal
|
|
188
55
|
*/
|
|
189
|
-
declare class
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
56
|
+
declare class EncryptionKeyring {
|
|
57
|
+
private source;
|
|
58
|
+
private lastKeyId;
|
|
59
|
+
constructor(source: EncryptionKeySource | null);
|
|
60
|
+
/** `true` when the database opens under a key. */
|
|
61
|
+
get encrypted(): boolean;
|
|
62
|
+
/** The identifier that came with the key that the last open used, or `undefined` when it came with none. */
|
|
63
|
+
get keyId(): string | undefined;
|
|
64
|
+
/** The key function that the database currently opens under, or `null` for a plaintext database. */
|
|
65
|
+
get keySource(): EncryptionKeySource | null;
|
|
194
66
|
/**
|
|
195
|
-
*
|
|
67
|
+
* Makes the database open every later connection under a new key function, or as plaintext.
|
|
68
|
+
*
|
|
69
|
+
* @param source - The key function of the key that the file now holds, or `null` for a plaintext file.
|
|
196
70
|
*/
|
|
197
|
-
|
|
198
|
-
constructor(
|
|
71
|
+
replace(source: EncryptionKeySource | null): void;
|
|
199
72
|
/**
|
|
200
|
-
*
|
|
73
|
+
* Calls the key function once, passes the key to the opens, and wipes Sirannon's copy of the key once they settle.
|
|
74
|
+
*
|
|
75
|
+
* @param open - Opens the connections with the settings that carry the key.
|
|
76
|
+
* @returns What `open` returns.
|
|
201
77
|
*/
|
|
202
|
-
|
|
78
|
+
openWith<T>(open: (options: KeyedOpenOptions, key: ResolvedEncryptionKey | undefined) => Promise<T>): Promise<T>;
|
|
203
79
|
/**
|
|
204
|
-
*
|
|
80
|
+
* Calls the key function and returns a copy of the key bytes, which the caller hands to a writer worker and wipes.
|
|
81
|
+
*
|
|
82
|
+
* @returns The key bytes.
|
|
205
83
|
*/
|
|
206
|
-
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* Thrown when Sirannon cannot load a compiled SQLite extension. The message
|
|
210
|
-
* names the extension path, and the optional `cause` gives the reason that
|
|
211
|
-
* SQLite or Sirannon reported.
|
|
212
|
-
*
|
|
213
|
-
* @public
|
|
214
|
-
*/
|
|
215
|
-
declare class ExtensionError extends SirannonError {
|
|
216
|
-
constructor(path: string, cause?: string);
|
|
84
|
+
freshKeyBytes(): Promise<Uint8Array>;
|
|
217
85
|
}
|
|
218
86
|
|
|
219
87
|
/**
|
|
@@ -231,6 +99,8 @@ interface ConnectionPoolOptions {
|
|
|
231
99
|
walAutoCheckpoint?: number;
|
|
232
100
|
useWriterWorker?: boolean;
|
|
233
101
|
workerHostOptions?: WorkerHostOptions;
|
|
102
|
+
keyring?: EncryptionKeyring;
|
|
103
|
+
prepareReopened?: (connections: readonly SQLiteConnection[]) => Promise<void>;
|
|
234
104
|
}
|
|
235
105
|
/**
|
|
236
106
|
* Opens one writer connection and a set of reader connections for a single database file, and returns the readers in rotation.
|
|
@@ -238,18 +108,62 @@ interface ConnectionPoolOptions {
|
|
|
238
108
|
* @internal
|
|
239
109
|
*/
|
|
240
110
|
declare class ConnectionPool {
|
|
241
|
-
private readonly
|
|
242
|
-
private
|
|
111
|
+
private readonly options;
|
|
112
|
+
private writer;
|
|
113
|
+
private readers;
|
|
243
114
|
private readerIndex;
|
|
244
115
|
private closed;
|
|
116
|
+
private isSuspended;
|
|
117
|
+
private readsInFlight;
|
|
118
|
+
private readsSettled;
|
|
119
|
+
private reopenFailure;
|
|
245
120
|
private constructor();
|
|
246
121
|
static create(options: ConnectionPoolOptions): Promise<ConnectionPool>;
|
|
122
|
+
private ensureAvailable;
|
|
247
123
|
acquireReader(): SQLiteConnection;
|
|
248
124
|
acquireWriter(): SQLiteConnection;
|
|
125
|
+
/**
|
|
126
|
+
* Returns the next reader connection and keeps it open until the caller passes the lease back through
|
|
127
|
+
* {@link ConnectionPool.releaseReader}, so that {@link ConnectionPool.closeReaders} closes no reader under a read.
|
|
128
|
+
*
|
|
129
|
+
* @returns The reader connection, which the caller releases exactly once when its read settles.
|
|
130
|
+
*/
|
|
131
|
+
leaseReader(): SQLiteConnection;
|
|
132
|
+
/** Ends a lease that {@link ConnectionPool.leaseReader} returned. */
|
|
133
|
+
releaseReader(): void;
|
|
134
|
+
/**
|
|
135
|
+
* Returns what a read on the next reader connection returns, and keeps that connection open until the read settles,
|
|
136
|
+
* so that {@link ConnectionPool.closeReaders} closes no reader under a read.
|
|
137
|
+
*
|
|
138
|
+
* @param read - The read to run on the reader.
|
|
139
|
+
* @returns The value of the read.
|
|
140
|
+
*/
|
|
141
|
+
withReader<T>(read: (conn: SQLiteConnection) => Promise<T>): Promise<T>;
|
|
249
142
|
/** Returns the writer and every reader, so that the caller can apply an operation to every connection in the pool. */
|
|
250
143
|
connections(): readonly SQLiteConnection[];
|
|
251
144
|
get readerCount(): number;
|
|
252
145
|
get isReadOnly(): boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Waits for every read on a reader to settle, then closes every reader and leaves the writer open, so that a
|
|
148
|
+
* checkpoint on the writer can reach the end of the log. Every acquire fails with `ENCRYPTION_CHANGE_IN_PROGRESS`
|
|
149
|
+
* until {@link ConnectionPool.reopen} returns.
|
|
150
|
+
*
|
|
151
|
+
* @param drainTimeoutMs - How long to wait for the reads to settle.
|
|
152
|
+
* @throws An `EncryptionError` with `ENCRYPTION_CHANGE_ABORTED` when a read runs past the timeout, which leaves the
|
|
153
|
+
* readers open and the pool available.
|
|
154
|
+
*/
|
|
155
|
+
closeReaders(drainTimeoutMs: number): Promise<void>;
|
|
156
|
+
private readsDrained;
|
|
157
|
+
/** Closes the writer after {@link ConnectionPool.closeReaders}. */
|
|
158
|
+
closeWriter(): Promise<void>;
|
|
159
|
+
/** `true` from {@link ConnectionPool.closeReaders} until {@link ConnectionPool.reopen} returns. */
|
|
160
|
+
get suspended(): boolean;
|
|
161
|
+
/**
|
|
162
|
+
* Opens the writer and the readers again, under the key that the pool's keyring holds now, and loads into them
|
|
163
|
+
* every extension that the database loaded into the connections they replace. When the connections fail to open,
|
|
164
|
+
* every acquire fails with that error until a later reopen succeeds.
|
|
165
|
+
*/
|
|
166
|
+
reopen(): Promise<void>;
|
|
253
167
|
close(): Promise<void>;
|
|
254
168
|
}
|
|
255
169
|
|
|
@@ -360,6 +274,7 @@ declare class DatabaseCdcController {
|
|
|
360
274
|
private stopPolling;
|
|
361
275
|
private stamper;
|
|
362
276
|
private epochRequest;
|
|
277
|
+
private readonly liveConnectionListeners;
|
|
363
278
|
constructor(runExclusive: RunExclusive$1, acquireWriter: () => SQLiteConnection, pollInterval: number, retention: number, openSnapshotConnection: (() => Promise<SQLiteConnection>) | null, deviceRetention: DeviceRetentionPolicy, onDispatched?: ChangeDispatchObserver | undefined);
|
|
364
279
|
ensureEpoch(): Promise<string>;
|
|
365
280
|
readAtPositionWith<T>(read: (conn: SQLiteConnection) => Promise<T>): Promise<{
|
|
@@ -372,6 +287,27 @@ declare class DatabaseCdcController {
|
|
|
372
287
|
run: RunExclusive$1;
|
|
373
288
|
}>;
|
|
374
289
|
closeLiveConnection(): Promise<void>;
|
|
290
|
+
/**
|
|
291
|
+
* Registers a function that the controller calls when a key change closes the live connection to replace the file,
|
|
292
|
+
* so that each live query plans again on the connection that opens afterwards.
|
|
293
|
+
*
|
|
294
|
+
* @param listener - The function to call.
|
|
295
|
+
* @returns A function that removes the registration.
|
|
296
|
+
*/
|
|
297
|
+
onLiveConnectionReplaced(listener: () => void): () => void;
|
|
298
|
+
/**
|
|
299
|
+
* Closes the live connection before a key change replaces the file, after telling every live query to plan again
|
|
300
|
+
* on the connection that the next call opens once the replacement ends. Where live queries read through the
|
|
301
|
+
* pool's writer, {@link DatabaseCdcController.resumeOnReopenedPool} tells them instead, once that writer exists.
|
|
302
|
+
*/
|
|
303
|
+
releaseLiveConnection(): Promise<void>;
|
|
304
|
+
/**
|
|
305
|
+
* Starts polling again where polling was on, and has every live query that reads through the pool's writer plan
|
|
306
|
+
* again, after the pool opened its connections to the file that a key change left in place. The key change calls
|
|
307
|
+
* this while it holds the writer, so no live read reaches the closed writer.
|
|
308
|
+
*/
|
|
309
|
+
resumeOnReopenedPool(): void;
|
|
310
|
+
private replanLiveQueries;
|
|
375
311
|
get subscriptions(): SubscriptionManager | null;
|
|
376
312
|
get changeTracker(): ChangeTracker | null;
|
|
377
313
|
watch(table: string): Promise<void>;
|
|
@@ -638,6 +574,7 @@ declare class DatabaseSyncController {
|
|
|
638
574
|
private readonly acquireWriter;
|
|
639
575
|
private readonly cdc;
|
|
640
576
|
private pkResolver;
|
|
577
|
+
private cachedOn;
|
|
641
578
|
private tablesReady;
|
|
642
579
|
private metaReady;
|
|
643
580
|
private outboxReader;
|
|
@@ -668,6 +605,7 @@ declare class DatabaseSyncController {
|
|
|
668
605
|
private setMetaSeq;
|
|
669
606
|
private ensureMeta;
|
|
670
607
|
private ensureSyncTables;
|
|
608
|
+
private resolverOn;
|
|
671
609
|
private ensureOutboxReader;
|
|
672
610
|
private ensureApplier;
|
|
673
611
|
private catchUpLocalColumnVersions;
|
|
@@ -754,11 +692,212 @@ declare class DatabaseWriteController {
|
|
|
754
692
|
private runInTransaction;
|
|
755
693
|
}
|
|
756
694
|
|
|
695
|
+
/**
|
|
696
|
+
* Counts the replication engines that write to one database through a separate writer connection, so that the
|
|
697
|
+
* database can refuse an operation that would replace its file under those connections.
|
|
698
|
+
*
|
|
699
|
+
* @internal
|
|
700
|
+
*/
|
|
701
|
+
declare class RegisteredReplicationEngines {
|
|
702
|
+
private readonly databaseId;
|
|
703
|
+
private count;
|
|
704
|
+
private readonly replacements;
|
|
705
|
+
constructor(databaseId: string);
|
|
706
|
+
/**
|
|
707
|
+
* Records one running engine, and returns the call that removes the record, which does nothing after its first
|
|
708
|
+
* call.
|
|
709
|
+
*
|
|
710
|
+
* @returns The call that removes the record.
|
|
711
|
+
* @throws The error of a file replacement under way, which would leave the engine on the replaced file.
|
|
712
|
+
*/
|
|
713
|
+
register(): () => void;
|
|
714
|
+
/**
|
|
715
|
+
* Throws when an engine runs, because the engine's writer connection would stay on the replaced file.
|
|
716
|
+
*
|
|
717
|
+
* @param operation - The operation that would replace the file, as the error message states it.
|
|
718
|
+
* @throws A `ReplicationError` with `REPLICATION_ACTIVE` while an engine runs.
|
|
719
|
+
*/
|
|
720
|
+
assertNone(operation: string): void;
|
|
721
|
+
/**
|
|
722
|
+
* Refuses the operation while an engine runs, and otherwise refuses every engine that starts before the returned
|
|
723
|
+
* call ends the replacement.
|
|
724
|
+
*
|
|
725
|
+
* @param operation - The operation that replaces the file, as the error message states it.
|
|
726
|
+
* @param refuseEngine - Builds the error that an engine which starts during the replacement receives.
|
|
727
|
+
* @returns The call that ends the replacement.
|
|
728
|
+
* @throws A `ReplicationError` with `REPLICATION_ACTIVE` while an engine runs.
|
|
729
|
+
*/
|
|
730
|
+
beginReplacement(operation: string, refuseEngine: () => SirannonError): () => void;
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Records the resolved path of every compiled extension that a database has
|
|
735
|
+
* loaded, and tracks every connection that the database opens beyond its pool,
|
|
736
|
+
* so that each of those connections can call the extensions' functions. SQLite
|
|
737
|
+
* scopes a loaded extension to the connection that loaded it, and a database
|
|
738
|
+
* opens a new connection for each consistent snapshot read and one more for its
|
|
739
|
+
* live queries.
|
|
740
|
+
*
|
|
741
|
+
* This class performs loads and opens one at a time, so a connection either
|
|
742
|
+
* opens after a load and loads that extension as it opens, or opens before the
|
|
743
|
+
* load and is one of the connections that the load covers.
|
|
744
|
+
*
|
|
745
|
+
* @internal
|
|
746
|
+
*/
|
|
747
|
+
declare class LoadedExtensions {
|
|
748
|
+
private readonly driver;
|
|
749
|
+
private readonly resolvedPaths;
|
|
750
|
+
private readonly openedConnections;
|
|
751
|
+
private queue;
|
|
752
|
+
constructor(driver: SQLiteDriver);
|
|
753
|
+
private runInTurn;
|
|
754
|
+
private loadRecorded;
|
|
755
|
+
/** Loads an extension into the pool's connections and every tracked connection, then records its resolved path. */
|
|
756
|
+
load(poolConnections: readonly SQLiteConnection[], extensionPath: string): Promise<void>;
|
|
757
|
+
/** Loads every recorded extension into connections that replaced the ones that the database loaded them into. */
|
|
758
|
+
reload(connections: readonly SQLiteConnection[]): Promise<void>;
|
|
759
|
+
/**
|
|
760
|
+
* Opens a connection, loads every recorded extension into it, and returns a
|
|
761
|
+
* wrapper that forwards each call to it. Closing the wrapper stops the
|
|
762
|
+
* tracking and closes the connection underneath.
|
|
763
|
+
*
|
|
764
|
+
* @param openConnection - The function that opens the connection that this database needs.
|
|
765
|
+
* @returns The wrapper to read and write through.
|
|
766
|
+
*/
|
|
767
|
+
open(openConnection: () => Promise<SQLiteConnection>): Promise<SQLiteConnection>;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
* A part of the database that keeps a connection to the file open between calls, and closes and reopens it when a
|
|
772
|
+
* key change replaces the file.
|
|
773
|
+
*
|
|
774
|
+
* @internal
|
|
775
|
+
*/
|
|
776
|
+
interface FileConnectionHolder {
|
|
777
|
+
/** Closes the held connection and stops the work that uses it. */
|
|
778
|
+
release(): Promise<void>;
|
|
779
|
+
/** Opens a new connection to the file that the key change left in place, and resumes the work that uses it. */
|
|
780
|
+
reopen(): Promise<void>;
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* Opens every connection to a database file beyond the pool, under the database's current key and with its loaded
|
|
784
|
+
* extensions, and tracks each one, so that a key change can close all of them before it replaces the file and open
|
|
785
|
+
* them again afterwards.
|
|
786
|
+
*
|
|
787
|
+
* @internal
|
|
788
|
+
*/
|
|
789
|
+
declare class DatabaseFileConnections {
|
|
790
|
+
private readonly driver;
|
|
791
|
+
private readonly path;
|
|
792
|
+
private readonly keyring;
|
|
793
|
+
private readonly extensions;
|
|
794
|
+
private active;
|
|
795
|
+
private readonly holders;
|
|
796
|
+
private replacement;
|
|
797
|
+
private drained;
|
|
798
|
+
constructor(driver: SQLiteDriver, path: string, keyring: EncryptionKeyring, extensions: LoadedExtensions);
|
|
799
|
+
/**
|
|
800
|
+
* Opens a connection to the database file, after any file replacement under way has ended.
|
|
801
|
+
*
|
|
802
|
+
* @param options - The open settings, without a key, which this method adds.
|
|
803
|
+
* @returns The connection, which the caller closes.
|
|
804
|
+
*/
|
|
805
|
+
open(options: OpenOptions): Promise<SQLiteConnection>;
|
|
806
|
+
private settle;
|
|
807
|
+
/**
|
|
808
|
+
* Registers a part of the database that keeps a connection open between calls.
|
|
809
|
+
*
|
|
810
|
+
* @param holder - The release and reopen calls of that part.
|
|
811
|
+
* @returns A function that removes the registration.
|
|
812
|
+
*/
|
|
813
|
+
hold(holder: FileConnectionHolder): () => void;
|
|
814
|
+
/**
|
|
815
|
+
* Makes later opens wait, has every holder close its connection, and waits until every other connection to the
|
|
816
|
+
* file has closed.
|
|
817
|
+
*
|
|
818
|
+
* @param timeoutMs - How long to wait for the connections that a call holds for the duration of one read.
|
|
819
|
+
* @throws An `EncryptionError` with `ENCRYPTION_CHANGE_ABORTED` when a connection stays open past the deadline.
|
|
820
|
+
*/
|
|
821
|
+
closeForReplacement(timeoutMs: number): Promise<void>;
|
|
822
|
+
/** Lets opens proceed again, and has every holder open its connection to the file that is now in place. */
|
|
823
|
+
reopenAfterReplacement(): Promise<void>;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
* The parts of an open database that a key change works through.
|
|
828
|
+
*
|
|
829
|
+
* @internal
|
|
830
|
+
*/
|
|
831
|
+
interface KeyChangeDeps {
|
|
832
|
+
path: string;
|
|
833
|
+
driver: SQLiteDriver;
|
|
834
|
+
keyring: EncryptionKeyring;
|
|
835
|
+
pool: ConnectionPool;
|
|
836
|
+
writerLock: WriterLock;
|
|
837
|
+
fileConnections: DatabaseFileConnections;
|
|
838
|
+
cdc: DatabaseCdcController;
|
|
839
|
+
backups: DatabaseBackupController;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
/**
|
|
843
|
+
* What the encryption controller needs beyond the parts that a key change works through.
|
|
844
|
+
*
|
|
845
|
+
* @internal
|
|
846
|
+
*/
|
|
847
|
+
interface EncryptionControllerDeps extends KeyChangeDeps {
|
|
848
|
+
databaseId: string;
|
|
849
|
+
readOnly: boolean;
|
|
850
|
+
replicationEngines: RegisteredReplicationEngines;
|
|
851
|
+
onKeyChanged?: (key: EncryptionKeySource | null) => void;
|
|
852
|
+
}
|
|
853
|
+
/**
|
|
854
|
+
* Reports how a database is encrypted, and runs one key change at a time.
|
|
855
|
+
*
|
|
856
|
+
* @internal
|
|
857
|
+
*/
|
|
858
|
+
declare class DatabaseEncryptionController {
|
|
859
|
+
private readonly deps;
|
|
860
|
+
private change;
|
|
861
|
+
private running;
|
|
862
|
+
private closing;
|
|
863
|
+
private described;
|
|
864
|
+
constructor(deps: EncryptionControllerDeps);
|
|
865
|
+
/** `true` while the database file opens under a key. */
|
|
866
|
+
get encrypted(): boolean;
|
|
867
|
+
/**
|
|
868
|
+
* Returns whether the file is encrypted, the scheme that it is encrypted under, the engine's version, the stored
|
|
869
|
+
* key identifier and change time, and the current or last key change.
|
|
870
|
+
*
|
|
871
|
+
* @returns The status.
|
|
872
|
+
*/
|
|
873
|
+
status(): Promise<EncryptionStatus>;
|
|
874
|
+
/**
|
|
875
|
+
* Encrypts the database, changes its key, or removes encryption, and resolves once the change ends.
|
|
876
|
+
*
|
|
877
|
+
* @param change - The target key function, or `null` for a plaintext file.
|
|
878
|
+
* @returns The status after the change.
|
|
879
|
+
* @throws `READ_ONLY` on a read-only database, `ENCRYPTION_CHANGE_IN_PROGRESS` while another change runs,
|
|
880
|
+
* `REPLICATION_ACTIVE` while a replication engine writes to the database, and the error that stopped the change.
|
|
881
|
+
*/
|
|
882
|
+
changeKey(change: EncryptionChange): Promise<EncryptionStatus>;
|
|
883
|
+
private runChange;
|
|
884
|
+
/** Stops a running key change at its next step, and waits for it to leave the database as it was. */
|
|
885
|
+
cancel(): Promise<void>;
|
|
886
|
+
private targetOf;
|
|
887
|
+
private finished;
|
|
888
|
+
private failed;
|
|
889
|
+
private describeFile;
|
|
890
|
+
}
|
|
891
|
+
|
|
757
892
|
interface DatabaseInternals {
|
|
758
893
|
parentHooks?: HookRegistry;
|
|
759
894
|
metrics?: MetricsCollector;
|
|
895
|
+
onEncryptionChanged?: (key: EncryptionKeySource | null) => void;
|
|
760
896
|
}
|
|
761
897
|
interface DatabaseRuntime {
|
|
898
|
+
fileConnections: DatabaseFileConnections;
|
|
899
|
+
encryption: DatabaseEncryptionController;
|
|
900
|
+
replicationEngines: RegisteredReplicationEngines;
|
|
762
901
|
pool: ConnectionPool;
|
|
763
902
|
writeGate: WriteGate;
|
|
764
903
|
writerLock: WriterLock;
|
|
@@ -1003,6 +1142,94 @@ declare class DatabaseBackups extends DatabaseLifecycle {
|
|
|
1003
1142
|
backupPiecesSafeToDelete(options?: BackupSafeToDeleteOptions): Promise<BackupChainRecord[]>;
|
|
1004
1143
|
}
|
|
1005
1144
|
|
|
1145
|
+
/**
|
|
1146
|
+
* Gives an open database its encryption methods: the status of its key, and the key change that encrypts it, gives it
|
|
1147
|
+
* a new key, or removes encryption while it stays open.
|
|
1148
|
+
*
|
|
1149
|
+
* Open a database through {@link Sirannon.open}, which returns a {@link Database} that extends this class.
|
|
1150
|
+
*
|
|
1151
|
+
* @public
|
|
1152
|
+
*/
|
|
1153
|
+
declare class DatabaseEncryption extends DatabaseBackups {
|
|
1154
|
+
/**
|
|
1155
|
+
* Returns whether the database file holds ciphertext, the version of the encryption engine, the identifier that
|
|
1156
|
+
* came with the current key, the time of the last finished key change, and the progress of the current or last
|
|
1157
|
+
* key change. The status never contains a key.
|
|
1158
|
+
*
|
|
1159
|
+
* @returns The encryption status.
|
|
1160
|
+
*/
|
|
1161
|
+
encryptionStatus(): Promise<EncryptionStatus>;
|
|
1162
|
+
/**
|
|
1163
|
+
* Encrypts a plaintext database, gives an encrypted one a new key, or, with `key` set to `null`, stores it as
|
|
1164
|
+
* plaintext, while the database stays open for reads and writes.
|
|
1165
|
+
*
|
|
1166
|
+
* Sirannon copies a snapshot to a new file under the target key, applies the writes committed since the snapshot in
|
|
1167
|
+
* rounds, holds writes only for the last round, and then replaces the file. Until the replacement, the database
|
|
1168
|
+
* keeps its current key. After it, every connection opens under the new key, so open the database under that key
|
|
1169
|
+
* from then on. When the database captures backups, the next capture starts a new chain with a full copy under the
|
|
1170
|
+
* new key.
|
|
1171
|
+
*
|
|
1172
|
+
* On the Expo driver, the change needs expo-file-system 19.0.0 or later. Once an app has called this method, keep
|
|
1173
|
+
* expo-file-system 19.0.0 or later installed in every later build, because the open that recovers from an
|
|
1174
|
+
* interrupted change reads the files beside the database through it. Without it, the open cannot see that a change
|
|
1175
|
+
* stopped part way.
|
|
1176
|
+
*
|
|
1177
|
+
* @param change - The function that returns the target key, or `null` to remove encryption.
|
|
1178
|
+
* @returns The encryption status once the change ends.
|
|
1179
|
+
* @throws An `EncryptionError` with `ENCRYPTION_UNSUPPORTED` on an Expo app without expo-file-system 19.0.0 or
|
|
1180
|
+
* later, before the change writes any file, with `ENCRYPTION_CHANGE_IN_PROGRESS` while another change runs, or with
|
|
1181
|
+
* `ENCRYPTION_CHANGE_ABORTED` when a schema change or a write that the change cannot apply exactly stops it, which
|
|
1182
|
+
* leaves the database under its current key, `READ_ONLY` on a read-only database, and a `ReplicationError` with
|
|
1183
|
+
* `REPLICATION_ACTIVE` while a replication engine writes to the database, which the caller stops before the change
|
|
1184
|
+
* and starts again afterwards.
|
|
1185
|
+
*/
|
|
1186
|
+
changeEncryption(change: EncryptionChange): Promise<EncryptionStatus>;
|
|
1187
|
+
/**
|
|
1188
|
+
* Opens a connection to this database's file beyond the pool, under the database's current key, which waits while
|
|
1189
|
+
* a key change replaces the file. The caller closes the connection.
|
|
1190
|
+
*
|
|
1191
|
+
* @param options - The open settings, without a key.
|
|
1192
|
+
* @returns The connection.
|
|
1193
|
+
* @internal
|
|
1194
|
+
*/
|
|
1195
|
+
openFileConnection(options: OpenOptions): Promise<SQLiteConnection>;
|
|
1196
|
+
/**
|
|
1197
|
+
* Registers a part of the server that keeps a connection from {@link DatabaseEncryption.openFileConnection} open
|
|
1198
|
+
* between calls, so that a key change can close it before it replaces the file and reopen it afterwards.
|
|
1199
|
+
*
|
|
1200
|
+
* @param holder - The release and reopen calls.
|
|
1201
|
+
* @returns A function that removes the registration.
|
|
1202
|
+
* @internal
|
|
1203
|
+
*/
|
|
1204
|
+
holdFileConnection(holder: FileConnectionHolder): () => void;
|
|
1205
|
+
/**
|
|
1206
|
+
* Returns whether the database file opens under a key, which a replication engine announces to its peers. A key
|
|
1207
|
+
* change can alter it only while no engine runs, so the value holds for an engine's whole run.
|
|
1208
|
+
*
|
|
1209
|
+
* @returns `true` for an encrypted database.
|
|
1210
|
+
* @internal
|
|
1211
|
+
*/
|
|
1212
|
+
get encryptedFile(): boolean;
|
|
1213
|
+
/**
|
|
1214
|
+
* Records a replication engine that writes to this database through a separate writer connection, so that a key
|
|
1215
|
+
* change or a restore refuses to replace the file under that connection while the engine runs.
|
|
1216
|
+
*
|
|
1217
|
+
* @returns A function that removes the record, which the engine calls when it stops.
|
|
1218
|
+
* @throws `ENCRYPTION_CHANGE_IN_PROGRESS` while a key change runs, and `DATABASE_CLOSED` on a closed database.
|
|
1219
|
+
* @internal
|
|
1220
|
+
*/
|
|
1221
|
+
registerReplicationEngine(): () => void;
|
|
1222
|
+
/**
|
|
1223
|
+
* Throws while a replication engine writes to this database, because replacing the file would leave the engine's
|
|
1224
|
+
* writer connection on the replaced file.
|
|
1225
|
+
*
|
|
1226
|
+
* @param operation - The operation that would replace the file, as the error message states it.
|
|
1227
|
+
* @throws A `ReplicationError` with `REPLICATION_ACTIVE` while an engine runs.
|
|
1228
|
+
* @internal
|
|
1229
|
+
*/
|
|
1230
|
+
assertNoReplicationEngine(operation: string): void;
|
|
1231
|
+
}
|
|
1232
|
+
|
|
1006
1233
|
/**
|
|
1007
1234
|
* An open SQLite database, with methods for reads, writes, transactions, migrations, change subscriptions, and live queries.
|
|
1008
1235
|
*
|
|
@@ -1010,7 +1237,7 @@ declare class DatabaseBackups extends DatabaseLifecycle {
|
|
|
1010
1237
|
*
|
|
1011
1238
|
* @public
|
|
1012
1239
|
*/
|
|
1013
|
-
declare class Database extends
|
|
1240
|
+
declare class Database extends DatabaseEncryption {
|
|
1014
1241
|
/** @internal */
|
|
1015
1242
|
static create(id: string, path: string, driver: SQLiteDriver, options?: DatabaseOptions, internals?: DatabaseInternals): Promise<Database>;
|
|
1016
1243
|
/** @internal */
|
|
@@ -1231,4 +1458,4 @@ declare class Database extends DatabaseBackups {
|
|
|
1231
1458
|
onAfterQuery(hook: AfterQueryHook): HookDispose;
|
|
1232
1459
|
}
|
|
1233
1460
|
|
|
1234
|
-
export {
|
|
1461
|
+
export { ConnectionPool as C, Database as D, HookRegistry as H, type PushHookContext as P, type SnapshotHookContext as S, type HookDispose as a, type DeviceSyncPort as b, type ConnectionPoolOptions as c, DatabaseBackups as d, DatabaseEncryption as e, DatabaseLifecycle as f, type HookEvent as g, type HookEventContextMap as h, type HookHandler as i, type SubscribeHookContext as j, HLC as k };
|