@capgo/capacitor-fast-sql 8.2.16 → 8.2.18
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 +17 -16
- package/android/build.gradle +1 -0
- package/android/consumer-rules.pro +14 -0
- package/android/src/main/java/app/capgo/capacitor/fastsql/CapgoCapacitorFastSqlPlugin.java +29 -6
- package/android/src/main/java/app/capgo/capacitor/fastsql/DatabaseConnection.java +2 -0
- package/android/src/main/java/app/capgo/capacitor/fastsql/EncryptedSQLDatabase.java +33 -46
- package/android/src/main/java/app/capgo/capacitor/fastsql/SQLDatabase.java +32 -50
- package/android/src/main/java/app/capgo/capacitor/fastsql/SQLHTTPServer.java +11 -23
- package/dist/esm/definitions.d.ts +17 -2
- package/dist/esm/definitions.d.ts.map +1 -1
- package/dist/esm/definitions.js +3 -1
- package/dist/esm/fast-sql.d.ts +4 -0
- package/dist/esm/fast-sql.d.ts.map +1 -1
- package/dist/esm/fast-sql.js +35 -3
- package/dist/esm/native-sql-connection.d.ts +1 -0
- package/dist/esm/native-sql-connection.d.ts.map +1 -1
- package/dist/esm/native-sql-connection.js +13 -6
- package/dist/esm/transaction-isolation.d.ts +3 -0
- package/dist/esm/transaction-isolation.d.ts.map +1 -0
- package/dist/esm/transaction-isolation.js +6 -0
- package/dist/esm/vector-store.d.ts.map +1 -1
- package/dist/esm/vector-store.js +5 -2
- package/dist/esm/web-sql-connection.d.ts.map +1 -1
- package/dist/esm/web-sql-connection.js +2 -0
- package/dist/esm/web.d.ts +2 -0
- package/dist/esm/web.d.ts.map +1 -1
- package/dist/esm/web.js +32 -4
- package/dist/plugin.cjs.js +93 -16
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +93 -16
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/CapgoCapacitorFastSqlPlugin/CapgoCapacitorFastSqlPlugin.swift +25 -3
- package/ios/Sources/CapgoCapacitorFastSqlPlugin/SQLDatabase.swift +15 -5
- package/ios/Sources/CapgoCapacitorFastSqlPlugin/SQLHTTPServer.swift +6 -0
- package/ios/Tests/CapgoCapacitorFastSqlPluginTests/CapgoCapacitorFastSqlPluginTests.swift +13 -3
- package/ios/Tests/CapgoCapacitorFastSqlPluginTests/SQLResultMetadataTests.swift +15 -0
- package/package.json +4 -2
package/dist/plugin.js
CHANGED
|
@@ -3,7 +3,9 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
3
3
|
|
|
4
4
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
5
5
|
/**
|
|
6
|
-
* Transaction isolation levels
|
|
6
|
+
* Transaction isolation levels. Only Serializable is supported by the current
|
|
7
|
+
* SQLite backends. Other values are retained for source compatibility but reject
|
|
8
|
+
* before starting a transaction; they are not silently mapped to another level.
|
|
7
9
|
*/
|
|
8
10
|
exports.IsolationLevel = void 0;
|
|
9
11
|
(function (IsolationLevel) {
|
|
@@ -17,6 +19,12 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
17
19
|
web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.CapgoCapacitorFastSqlWeb()),
|
|
18
20
|
});
|
|
19
21
|
|
|
22
|
+
function assertSupportedIsolation(level) {
|
|
23
|
+
if (level !== undefined && level !== exports.IsolationLevel.Serializable) {
|
|
24
|
+
throw new Error('Only SERIALIZABLE transaction isolation is supported');
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
20
28
|
/**
|
|
21
29
|
* SQL Connection class that uses HTTP protocol for efficient communication
|
|
22
30
|
* with native SQLite databases, bypassing Capacitor's standard bridge.
|
|
@@ -29,7 +37,12 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
29
37
|
this.database = database;
|
|
30
38
|
this.port = port;
|
|
31
39
|
this.token = token;
|
|
32
|
-
this.baseUrl = `http://
|
|
40
|
+
this.baseUrl = `http://127.0.0.1:${port}`;
|
|
41
|
+
}
|
|
42
|
+
browserFetch(input, init) {
|
|
43
|
+
const savedFetch = Reflect.get(globalThis, 'CapacitorWebFetch');
|
|
44
|
+
const browserFetch = typeof savedFetch === 'function' ? savedFetch : globalThis.fetch;
|
|
45
|
+
return browserFetch.call(globalThis, input, init);
|
|
33
46
|
}
|
|
34
47
|
/**
|
|
35
48
|
* Get the database name
|
|
@@ -45,7 +58,7 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
45
58
|
* @returns Query results
|
|
46
59
|
*/
|
|
47
60
|
async execute(statement, params) {
|
|
48
|
-
const response = await
|
|
61
|
+
const response = await this.browserFetch(`${this.baseUrl}/execute`, {
|
|
49
62
|
method: 'POST',
|
|
50
63
|
headers: {
|
|
51
64
|
'Content-Type': 'application/json',
|
|
@@ -71,7 +84,7 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
71
84
|
* @returns Array of results for each operation
|
|
72
85
|
*/
|
|
73
86
|
async executeBatch(operations) {
|
|
74
|
-
const response = await
|
|
87
|
+
const response = await this.browserFetch(`${this.baseUrl}/batch`, {
|
|
75
88
|
method: 'POST',
|
|
76
89
|
headers: {
|
|
77
90
|
'Content-Type': 'application/json',
|
|
@@ -98,10 +111,11 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
98
111
|
* @param isolationLevel - Optional isolation level
|
|
99
112
|
*/
|
|
100
113
|
async beginTransaction(isolationLevel) {
|
|
114
|
+
assertSupportedIsolation(isolationLevel);
|
|
101
115
|
if (this.inTransaction) {
|
|
102
116
|
throw new Error('Transaction already in progress');
|
|
103
117
|
}
|
|
104
|
-
const response = await
|
|
118
|
+
const response = await this.browserFetch(`${this.baseUrl}/transaction/begin`, {
|
|
105
119
|
method: 'POST',
|
|
106
120
|
headers: {
|
|
107
121
|
'Content-Type': 'application/json',
|
|
@@ -125,7 +139,7 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
125
139
|
if (!this.inTransaction) {
|
|
126
140
|
throw new Error('No transaction in progress');
|
|
127
141
|
}
|
|
128
|
-
const response = await
|
|
142
|
+
const response = await this.browserFetch(`${this.baseUrl}/transaction/commit`, {
|
|
129
143
|
method: 'POST',
|
|
130
144
|
headers: {
|
|
131
145
|
Authorization: `Bearer ${this.token}`,
|
|
@@ -145,7 +159,7 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
145
159
|
if (!this.inTransaction) {
|
|
146
160
|
throw new Error('No transaction in progress');
|
|
147
161
|
}
|
|
148
|
-
const response = await
|
|
162
|
+
const response = await this.browserFetch(`${this.baseUrl}/transaction/rollback`, {
|
|
149
163
|
method: 'POST',
|
|
150
164
|
headers: {
|
|
151
165
|
Authorization: `Bearer ${this.token}`,
|
|
@@ -306,6 +320,7 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
306
320
|
* @param isolationLevel - Optional isolation level
|
|
307
321
|
*/
|
|
308
322
|
async beginTransaction(isolationLevel) {
|
|
323
|
+
assertSupportedIsolation(isolationLevel);
|
|
309
324
|
if (this.inTransaction) {
|
|
310
325
|
throw new Error('Transaction already in progress');
|
|
311
326
|
}
|
|
@@ -400,12 +415,40 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
400
415
|
* @returns SQLConnection instance for executing queries
|
|
401
416
|
*/
|
|
402
417
|
static async connect(options) {
|
|
403
|
-
|
|
404
|
-
const
|
|
418
|
+
var _a;
|
|
419
|
+
const saved = this.openOptions.get(options.database);
|
|
420
|
+
if (saved && !this.optionsMatch(saved, options)) {
|
|
421
|
+
throw new Error(`Database '${options.database}' is already opening or open with different options`);
|
|
422
|
+
}
|
|
423
|
+
const existing = (_a = this.connections.get(options.database)) !== null && _a !== void 0 ? _a : this.opening.get(options.database);
|
|
405
424
|
if (existing) {
|
|
406
425
|
this.sharedConnections.add(options.database);
|
|
407
426
|
return existing;
|
|
408
427
|
}
|
|
428
|
+
const snapshot = Object.assign({}, options);
|
|
429
|
+
this.openOptions.set(options.database, snapshot);
|
|
430
|
+
const pending = this.open(snapshot);
|
|
431
|
+
this.opening.set(options.database, pending);
|
|
432
|
+
try {
|
|
433
|
+
return await pending;
|
|
434
|
+
}
|
|
435
|
+
catch (error) {
|
|
436
|
+
this.openOptions.delete(options.database);
|
|
437
|
+
this.sharedConnections.delete(options.database);
|
|
438
|
+
throw error;
|
|
439
|
+
}
|
|
440
|
+
finally {
|
|
441
|
+
this.opening.delete(options.database);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
static optionsMatch(left, right) {
|
|
445
|
+
return (Boolean(left.encrypted) === Boolean(right.encrypted) &&
|
|
446
|
+
left.encryptionKey === right.encryptionKey &&
|
|
447
|
+
Boolean(left.readOnly) === Boolean(right.readOnly) &&
|
|
448
|
+
Boolean(left.walMode) === Boolean(right.walMode) &&
|
|
449
|
+
Boolean(left.performancePresets) === Boolean(right.performancePresets));
|
|
450
|
+
}
|
|
451
|
+
static async open(options) {
|
|
409
452
|
// Connect via native plugin
|
|
410
453
|
const info = await CapgoCapacitorFastSql.connect(options);
|
|
411
454
|
// Create connection instance appropriate for the current platform
|
|
@@ -428,6 +471,7 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
428
471
|
*/
|
|
429
472
|
static async disconnect(database) {
|
|
430
473
|
var _a;
|
|
474
|
+
await this.opening.get(database);
|
|
431
475
|
const connection = this.connections.get(database);
|
|
432
476
|
if (!connection) {
|
|
433
477
|
throw new Error(`Database '${database}' is not connected`);
|
|
@@ -440,6 +484,7 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
440
484
|
await CapgoCapacitorFastSql.disconnect({ database });
|
|
441
485
|
// Remove connection
|
|
442
486
|
this.connections.delete(database);
|
|
487
|
+
this.openOptions.delete(database);
|
|
443
488
|
this.sharedConnections.delete(database);
|
|
444
489
|
this.connectionRetainers.delete(database);
|
|
445
490
|
this.pendingDisconnects.delete(database);
|
|
@@ -491,7 +536,7 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
491
536
|
* Close all open connections
|
|
492
537
|
*/
|
|
493
538
|
static async disconnectAll() {
|
|
494
|
-
const databases = Array.from(this.connections.keys());
|
|
539
|
+
const databases = Array.from(new Set([...this.connections.keys(), ...this.opening.keys()]));
|
|
495
540
|
await Promise.all(databases.map((db) => {
|
|
496
541
|
this.connectionRetainers.delete(db);
|
|
497
542
|
this.pendingDisconnects.delete(db);
|
|
@@ -507,6 +552,8 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
507
552
|
return Array.from(this.connections.keys());
|
|
508
553
|
}
|
|
509
554
|
}
|
|
555
|
+
FastSQL.opening = new Map();
|
|
556
|
+
FastSQL.openOptions = new Map();
|
|
510
557
|
FastSQL.connections = new Map();
|
|
511
558
|
FastSQL.sharedConnections = new Set();
|
|
512
559
|
FastSQL.connectionRetainers = new Map();
|
|
@@ -858,8 +905,11 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
858
905
|
.map((row) => this.rowToGetResult(row))
|
|
859
906
|
.filter(params.predicate)
|
|
860
907
|
.map((row) => row.id);
|
|
861
|
-
for (
|
|
862
|
-
await this.connection.
|
|
908
|
+
for (let offset = 0; offset < ids.length; offset += 100) {
|
|
909
|
+
await this.connection.executeBatch(ids.slice(offset, offset + 100).map((id) => ({
|
|
910
|
+
statement: `DELETE FROM ${VECTOR_TABLE} WHERE store = ? AND id = ?`,
|
|
911
|
+
params: [this.store, id],
|
|
912
|
+
})));
|
|
863
913
|
}
|
|
864
914
|
}
|
|
865
915
|
async query(params) {
|
|
@@ -16886,7 +16936,13 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
16886
16936
|
* Must be called before connect() when overriding the default worker.
|
|
16887
16937
|
*/
|
|
16888
16938
|
async configureWeb(config) {
|
|
16889
|
-
this.
|
|
16939
|
+
if (this.promiserPromise || this.databases.size > 0) {
|
|
16940
|
+
throw new Error('Configure web storage before opening the first database');
|
|
16941
|
+
}
|
|
16942
|
+
if (config.requirePersistence && config.useOpfs === false) {
|
|
16943
|
+
throw new Error('requirePersistence requires OPFS');
|
|
16944
|
+
}
|
|
16945
|
+
this.webConfig = Object.assign({}, config);
|
|
16890
16946
|
this.promiserPromise = null;
|
|
16891
16947
|
}
|
|
16892
16948
|
getPromiser() {
|
|
@@ -16897,28 +16953,37 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
16897
16953
|
return this.promiserPromise;
|
|
16898
16954
|
}
|
|
16899
16955
|
dbPath(database) {
|
|
16956
|
+
if (!database || database === '.' || database === '..' || /[/\\\0]/.test(database)) {
|
|
16957
|
+
throw new Error('Database must be a non-empty file name without path separators');
|
|
16958
|
+
}
|
|
16900
16959
|
return `/capgo-fast-sql/${database}.sqlite3`;
|
|
16901
16960
|
}
|
|
16902
16961
|
async connect(options) {
|
|
16962
|
+
if (options.readOnly) {
|
|
16963
|
+
throw new Error('Read-only opens are not supported by the SQLite Wasm Worker transport');
|
|
16964
|
+
}
|
|
16903
16965
|
if (this.databases.has(options.database)) {
|
|
16904
16966
|
const existing = this.databases.get(options.database);
|
|
16905
16967
|
return {
|
|
16906
16968
|
port: existing.port,
|
|
16907
16969
|
token: existing.token,
|
|
16908
16970
|
database: options.database,
|
|
16971
|
+
persistent: existing.persistent,
|
|
16909
16972
|
};
|
|
16910
16973
|
}
|
|
16911
|
-
const promiser = await this.getPromiser();
|
|
16912
16974
|
const path = this.dbPath(options.database);
|
|
16975
|
+
const promiser = await this.getPromiser();
|
|
16913
16976
|
const useOpfs = this.webConfig.useOpfs !== false;
|
|
16914
16977
|
let openResult;
|
|
16915
16978
|
if (useOpfs) {
|
|
16916
16979
|
try {
|
|
16917
16980
|
openResult = await promiser('open', {
|
|
16918
|
-
filename: `file
|
|
16981
|
+
filename: `file:/capgo-fast-sql/${encodeURIComponent(options.database)}.sqlite3?vfs=opfs`,
|
|
16919
16982
|
});
|
|
16920
16983
|
}
|
|
16921
16984
|
catch (opfsError) {
|
|
16985
|
+
if (this.webConfig.requirePersistence)
|
|
16986
|
+
throw opfsError;
|
|
16922
16987
|
console.warn('[CapgoCapacitorFastSql] OPFS unavailable; web database will not persist across reloads. ' +
|
|
16923
16988
|
'Serve with Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp.', opfsError);
|
|
16924
16989
|
openResult = await promiser('open', { filename: path });
|
|
@@ -16932,7 +16997,16 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
16932
16997
|
if (!dbId) {
|
|
16933
16998
|
throw new Error('Failed to open SQLite Wasm database: missing dbId');
|
|
16934
16999
|
}
|
|
16935
|
-
|
|
17000
|
+
try {
|
|
17001
|
+
if (this.webConfig.requirePersistence && !persistent) {
|
|
17002
|
+
throw new Error('SQLite Worker did not confirm persistent storage');
|
|
17003
|
+
}
|
|
17004
|
+
await this.applyPerformanceConfig(promiser, dbId, options);
|
|
17005
|
+
}
|
|
17006
|
+
catch (error) {
|
|
17007
|
+
await promiser({ type: 'close', dbId, args: {} });
|
|
17008
|
+
throw error;
|
|
17009
|
+
}
|
|
16936
17010
|
const token = this.generateToken();
|
|
16937
17011
|
const port = this.nextPort++;
|
|
16938
17012
|
this.databases.set(options.database, { dbId, token, port, persistent });
|
|
@@ -16940,6 +17014,7 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
16940
17014
|
port,
|
|
16941
17015
|
token,
|
|
16942
17016
|
database: options.database,
|
|
17017
|
+
persistent,
|
|
16943
17018
|
};
|
|
16944
17019
|
}
|
|
16945
17020
|
async disconnect(options) {
|
|
@@ -16960,6 +17035,7 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
16960
17035
|
return {
|
|
16961
17036
|
port: dbInfo.port,
|
|
16962
17037
|
token: dbInfo.token,
|
|
17038
|
+
persistent: dbInfo.persistent,
|
|
16963
17039
|
};
|
|
16964
17040
|
}
|
|
16965
17041
|
async execute(options) {
|
|
@@ -17007,6 +17083,7 @@ var capacitorCapgoCapacitorFastSql = (function (exports, core) {
|
|
|
17007
17083
|
}
|
|
17008
17084
|
}
|
|
17009
17085
|
async beginTransaction(options) {
|
|
17086
|
+
assertSupportedIsolation(options.isolationLevel);
|
|
17010
17087
|
await this.execute({
|
|
17011
17088
|
database: options.database,
|
|
17012
17089
|
statement: 'BEGIN TRANSACTION',
|