@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.
Files changed (37) hide show
  1. package/README.md +17 -16
  2. package/android/build.gradle +1 -0
  3. package/android/consumer-rules.pro +14 -0
  4. package/android/src/main/java/app/capgo/capacitor/fastsql/CapgoCapacitorFastSqlPlugin.java +29 -6
  5. package/android/src/main/java/app/capgo/capacitor/fastsql/DatabaseConnection.java +2 -0
  6. package/android/src/main/java/app/capgo/capacitor/fastsql/EncryptedSQLDatabase.java +33 -46
  7. package/android/src/main/java/app/capgo/capacitor/fastsql/SQLDatabase.java +32 -50
  8. package/android/src/main/java/app/capgo/capacitor/fastsql/SQLHTTPServer.java +11 -23
  9. package/dist/esm/definitions.d.ts +17 -2
  10. package/dist/esm/definitions.d.ts.map +1 -1
  11. package/dist/esm/definitions.js +3 -1
  12. package/dist/esm/fast-sql.d.ts +4 -0
  13. package/dist/esm/fast-sql.d.ts.map +1 -1
  14. package/dist/esm/fast-sql.js +35 -3
  15. package/dist/esm/native-sql-connection.d.ts +1 -0
  16. package/dist/esm/native-sql-connection.d.ts.map +1 -1
  17. package/dist/esm/native-sql-connection.js +13 -6
  18. package/dist/esm/transaction-isolation.d.ts +3 -0
  19. package/dist/esm/transaction-isolation.d.ts.map +1 -0
  20. package/dist/esm/transaction-isolation.js +6 -0
  21. package/dist/esm/vector-store.d.ts.map +1 -1
  22. package/dist/esm/vector-store.js +5 -2
  23. package/dist/esm/web-sql-connection.d.ts.map +1 -1
  24. package/dist/esm/web-sql-connection.js +2 -0
  25. package/dist/esm/web.d.ts +2 -0
  26. package/dist/esm/web.d.ts.map +1 -1
  27. package/dist/esm/web.js +32 -4
  28. package/dist/plugin.cjs.js +93 -16
  29. package/dist/plugin.cjs.js.map +1 -1
  30. package/dist/plugin.js +93 -16
  31. package/dist/plugin.js.map +1 -1
  32. package/ios/Sources/CapgoCapacitorFastSqlPlugin/CapgoCapacitorFastSqlPlugin.swift +25 -3
  33. package/ios/Sources/CapgoCapacitorFastSqlPlugin/SQLDatabase.swift +15 -5
  34. package/ios/Sources/CapgoCapacitorFastSqlPlugin/SQLHTTPServer.swift +6 -0
  35. package/ios/Tests/CapgoCapacitorFastSqlPluginTests/CapgoCapacitorFastSqlPluginTests.swift +13 -3
  36. package/ios/Tests/CapgoCapacitorFastSqlPluginTests/SQLResultMetadataTests.swift +15 -0
  37. package/package.json +4 -2
@@ -16,12 +16,40 @@ export class FastSQL {
16
16
  * @returns SQLConnection instance for executing queries
17
17
  */
18
18
  static async connect(options) {
19
- // Check if already connected
20
- const existing = this.connections.get(options.database);
19
+ var _a;
20
+ const saved = this.openOptions.get(options.database);
21
+ if (saved && !this.optionsMatch(saved, options)) {
22
+ throw new Error(`Database '${options.database}' is already opening or open with different options`);
23
+ }
24
+ const existing = (_a = this.connections.get(options.database)) !== null && _a !== void 0 ? _a : this.opening.get(options.database);
21
25
  if (existing) {
22
26
  this.sharedConnections.add(options.database);
23
27
  return existing;
24
28
  }
29
+ const snapshot = Object.assign({}, options);
30
+ this.openOptions.set(options.database, snapshot);
31
+ const pending = this.open(snapshot);
32
+ this.opening.set(options.database, pending);
33
+ try {
34
+ return await pending;
35
+ }
36
+ catch (error) {
37
+ this.openOptions.delete(options.database);
38
+ this.sharedConnections.delete(options.database);
39
+ throw error;
40
+ }
41
+ finally {
42
+ this.opening.delete(options.database);
43
+ }
44
+ }
45
+ static optionsMatch(left, right) {
46
+ return (Boolean(left.encrypted) === Boolean(right.encrypted) &&
47
+ left.encryptionKey === right.encryptionKey &&
48
+ Boolean(left.readOnly) === Boolean(right.readOnly) &&
49
+ Boolean(left.walMode) === Boolean(right.walMode) &&
50
+ Boolean(left.performancePresets) === Boolean(right.performancePresets));
51
+ }
52
+ static async open(options) {
25
53
  // Connect via native plugin
26
54
  const info = await CapgoCapacitorFastSql.connect(options);
27
55
  // Create connection instance appropriate for the current platform
@@ -44,6 +72,7 @@ export class FastSQL {
44
72
  */
45
73
  static async disconnect(database) {
46
74
  var _a;
75
+ await this.opening.get(database);
47
76
  const connection = this.connections.get(database);
48
77
  if (!connection) {
49
78
  throw new Error(`Database '${database}' is not connected`);
@@ -56,6 +85,7 @@ export class FastSQL {
56
85
  await CapgoCapacitorFastSql.disconnect({ database });
57
86
  // Remove connection
58
87
  this.connections.delete(database);
88
+ this.openOptions.delete(database);
59
89
  this.sharedConnections.delete(database);
60
90
  this.connectionRetainers.delete(database);
61
91
  this.pendingDisconnects.delete(database);
@@ -107,7 +137,7 @@ export class FastSQL {
107
137
  * Close all open connections
108
138
  */
109
139
  static async disconnectAll() {
110
- const databases = Array.from(this.connections.keys());
140
+ const databases = Array.from(new Set([...this.connections.keys(), ...this.opening.keys()]));
111
141
  await Promise.all(databases.map((db) => {
112
142
  this.connectionRetainers.delete(db);
113
143
  this.pendingDisconnects.delete(db);
@@ -123,6 +153,8 @@ export class FastSQL {
123
153
  return Array.from(this.connections.keys());
124
154
  }
125
155
  }
156
+ FastSQL.opening = new Map();
157
+ FastSQL.openOptions = new Map();
126
158
  FastSQL.connections = new Map();
127
159
  FastSQL.sharedConnections = new Set();
128
160
  FastSQL.connectionRetainers = new Map();
@@ -14,6 +14,7 @@ export declare class NativeSQLConnection implements SQLConnection {
14
14
  private baseUrl;
15
15
  private inTransaction;
16
16
  constructor(database: string, port: number, token: string);
17
+ private browserFetch;
17
18
  /**
18
19
  * Get the database name
19
20
  */
@@ -1 +1 @@
1
- {"version":3,"file":"native-sql-connection.d.ts","sourceRoot":"","sources":["../../src/native-sql-connection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD;;;;;GAKG;AACH,qBAAa,mBAAoB,YAAW,aAAa;IACvD,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,aAAa,CAAS;gBAElB,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAOzD;;OAEG;IACH,eAAe,IAAI,MAAM;IAIzB;;;;;;OAMG;IACG,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC;IAuBzE;;;;;OAKG;IACG,YAAY,CAAC,UAAU,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAyBzE;;;;OAIG;IACG,gBAAgB,CAAC,cAAc,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBtE;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB7B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB/B;;;;;OAKG;IACG,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAYhH;;;;;;OAMG;IACG,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAKtE;;;;;;OAMG;IACG,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAQvG;;;OAGG;IACH,OAAO,CAAC,eAAe;IAYvB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAkBzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAQ1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAQ3B"}
1
+ {"version":3,"file":"native-sql-connection.d.ts","sourceRoot":"","sources":["../../src/native-sql-connection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGtD;;;;;GAKG;AACH,qBAAa,mBAAoB,YAAW,aAAa;IACvD,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,aAAa,CAAS;gBAElB,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;IAOzD,OAAO,CAAC,YAAY;IAMpB;;OAEG;IACH,eAAe,IAAI,MAAM;IAIzB;;;;;;OAMG;IACG,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC;IAuBzE;;;;;OAKG;IACG,YAAY,CAAC,UAAU,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAyBzE;;;;OAIG;IACG,gBAAgB,CAAC,cAAc,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BtE;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB7B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB/B;;;;;OAKG;IACG,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAYhH;;;;;;OAMG;IACG,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAKtE;;;;;;OAMG;IACG,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAQvG;;;OAGG;IACH,OAAO,CAAC,eAAe;IAYvB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAkBzB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAQ1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAQ3B"}
@@ -1,4 +1,5 @@
1
1
  import { IsolationLevel } from './definitions';
2
+ import { assertSupportedIsolation } from './transaction-isolation';
2
3
  /**
3
4
  * SQL Connection class that uses HTTP protocol for efficient communication
4
5
  * with native SQLite databases, bypassing Capacitor's standard bridge.
@@ -11,7 +12,12 @@ export class NativeSQLConnection {
11
12
  this.database = database;
12
13
  this.port = port;
13
14
  this.token = token;
14
- this.baseUrl = `http://localhost:${port}`;
15
+ this.baseUrl = `http://127.0.0.1:${port}`;
16
+ }
17
+ browserFetch(input, init) {
18
+ const savedFetch = Reflect.get(globalThis, 'CapacitorWebFetch');
19
+ const browserFetch = typeof savedFetch === 'function' ? savedFetch : globalThis.fetch;
20
+ return browserFetch.call(globalThis, input, init);
15
21
  }
16
22
  /**
17
23
  * Get the database name
@@ -27,7 +33,7 @@ export class NativeSQLConnection {
27
33
  * @returns Query results
28
34
  */
29
35
  async execute(statement, params) {
30
- const response = await fetch(`${this.baseUrl}/execute`, {
36
+ const response = await this.browserFetch(`${this.baseUrl}/execute`, {
31
37
  method: 'POST',
32
38
  headers: {
33
39
  'Content-Type': 'application/json',
@@ -53,7 +59,7 @@ export class NativeSQLConnection {
53
59
  * @returns Array of results for each operation
54
60
  */
55
61
  async executeBatch(operations) {
56
- const response = await fetch(`${this.baseUrl}/batch`, {
62
+ const response = await this.browserFetch(`${this.baseUrl}/batch`, {
57
63
  method: 'POST',
58
64
  headers: {
59
65
  'Content-Type': 'application/json',
@@ -80,10 +86,11 @@ export class NativeSQLConnection {
80
86
  * @param isolationLevel - Optional isolation level
81
87
  */
82
88
  async beginTransaction(isolationLevel) {
89
+ assertSupportedIsolation(isolationLevel);
83
90
  if (this.inTransaction) {
84
91
  throw new Error('Transaction already in progress');
85
92
  }
86
- const response = await fetch(`${this.baseUrl}/transaction/begin`, {
93
+ const response = await this.browserFetch(`${this.baseUrl}/transaction/begin`, {
87
94
  method: 'POST',
88
95
  headers: {
89
96
  'Content-Type': 'application/json',
@@ -107,7 +114,7 @@ export class NativeSQLConnection {
107
114
  if (!this.inTransaction) {
108
115
  throw new Error('No transaction in progress');
109
116
  }
110
- const response = await fetch(`${this.baseUrl}/transaction/commit`, {
117
+ const response = await this.browserFetch(`${this.baseUrl}/transaction/commit`, {
111
118
  method: 'POST',
112
119
  headers: {
113
120
  Authorization: `Bearer ${this.token}`,
@@ -127,7 +134,7 @@ export class NativeSQLConnection {
127
134
  if (!this.inTransaction) {
128
135
  throw new Error('No transaction in progress');
129
136
  }
130
- const response = await fetch(`${this.baseUrl}/transaction/rollback`, {
137
+ const response = await this.browserFetch(`${this.baseUrl}/transaction/rollback`, {
131
138
  method: 'POST',
132
139
  headers: {
133
140
  Authorization: `Bearer ${this.token}`,
@@ -0,0 +1,3 @@
1
+ import { IsolationLevel } from './definitions';
2
+ export declare function assertSupportedIsolation(level?: IsolationLevel): void;
3
+ //# sourceMappingURL=transaction-isolation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction-isolation.d.ts","sourceRoot":"","sources":["../../src/transaction-isolation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,wBAAgB,wBAAwB,CAAC,KAAK,CAAC,EAAE,cAAc,GAAG,IAAI,CAIrE"}
@@ -0,0 +1,6 @@
1
+ import { IsolationLevel } from './definitions';
2
+ export function assertSupportedIsolation(level) {
3
+ if (level !== undefined && level !== IsolationLevel.Serializable) {
4
+ throw new Error('Only SERIALIZABLE transaction isolation is supported');
5
+ }
6
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"vector-store.d.ts","sourceRoot":"","sources":["../../src/vector-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vector-store.d.ts","sourceRoot":"","sources":["../../src/vector-store.ts"],"names":[],"mappings":"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"}
@@ -162,8 +162,11 @@ export class FastSQLVectorStore {
162
162
  .map((row) => this.rowToGetResult(row))
163
163
  .filter(params.predicate)
164
164
  .map((row) => row.id);
165
- for (const id of ids) {
166
- await this.connection.run(`DELETE FROM ${VECTOR_TABLE} WHERE store = ? AND id = ?`, [this.store, id]);
165
+ for (let offset = 0; offset < ids.length; offset += 100) {
166
+ await this.connection.executeBatch(ids.slice(offset, offset + 100).map((id) => ({
167
+ statement: `DELETE FROM ${VECTOR_TABLE} WHERE store = ? AND id = ?`,
168
+ params: [this.store, id],
169
+ })));
167
170
  }
168
171
  }
169
172
  async query(params) {
@@ -1 +1 @@
1
- {"version":3,"file":"web-sql-connection.d.ts","sourceRoot":"","sources":["../../src/web-sql-connection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,2BAA2B,EAC3B,QAAQ,EACR,MAAM,EACN,SAAS,EACT,iBAAiB,EACjB,cAAc,EACf,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD;;;GAGG;AACH,qBAAa,gBAAiB,YAAW,aAAa;IACpD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,aAAa,CAAS;gBAElB,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,2BAA2B;IAKjE;;OAEG;IACH,eAAe,IAAI,MAAM;IAIzB;;;;;;OAMG;IACG,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC;IAIzE;;;;;OAKG;IACG,YAAY,CAAC,UAAU,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAQzE;;;;OAIG;IACG,gBAAgB,CAAC,cAAc,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAStE;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAS7B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAS/B;;;;;OAKG;IACG,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAsBhH;;;;;;OAMG;IACG,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAKtE;;;;;;OAMG;IACG,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAOxG"}
1
+ {"version":3,"file":"web-sql-connection.d.ts","sourceRoot":"","sources":["../../src/web-sql-connection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,2BAA2B,EAC3B,QAAQ,EACR,MAAM,EACN,SAAS,EACT,iBAAiB,EACjB,cAAc,EACf,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGtD;;;GAGG;AACH,qBAAa,gBAAiB,YAAW,aAAa;IACpD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,aAAa,CAAS;gBAElB,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,2BAA2B;IAKjE;;OAEG;IACH,eAAe,IAAI,MAAM;IAIzB;;;;;;OAMG;IACG,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC;IAIzE;;;;;OAKG;IACG,YAAY,CAAC,UAAU,EAAE,iBAAiB,EAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAQzE;;;;OAIG;IACG,gBAAgB,CAAC,cAAc,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAUtE;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAS7B;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAS/B;;;;;OAKG;IACG,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,OAAO,CAAC,CAAC,CAAC,EAAE,cAAc,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAsBhH;;;;;;OAMG;IACG,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAKtE;;;;;;OAMG;IACG,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAOxG"}
@@ -1,3 +1,4 @@
1
+ import { assertSupportedIsolation } from './transaction-isolation';
1
2
  /**
2
3
  * Web implementation of SQLConnection that calls the Capacitor plugin directly,
3
4
  * avoiding HTTP network requests which are not available on the web platform.
@@ -43,6 +44,7 @@ export class WebSQLConnection {
43
44
  * @param isolationLevel - Optional isolation level
44
45
  */
45
46
  async beginTransaction(isolationLevel) {
47
+ assertSupportedIsolation(isolationLevel);
46
48
  if (this.inTransaction) {
47
49
  throw new Error('Transaction already in progress');
48
50
  }
package/dist/esm/web.d.ts CHANGED
@@ -23,6 +23,7 @@ export declare class CapgoCapacitorFastSqlWeb extends WebPlugin implements Capgo
23
23
  port: number;
24
24
  token: string;
25
25
  database: string;
26
+ persistent: boolean;
26
27
  }>;
27
28
  disconnect(options: {
28
29
  database: string;
@@ -32,6 +33,7 @@ export declare class CapgoCapacitorFastSqlWeb extends WebPlugin implements Capgo
32
33
  }): Promise<{
33
34
  port: number;
34
35
  token: string;
36
+ persistent: boolean;
35
37
  }>;
36
38
  execute(options: {
37
39
  database: string;
@@ -1 +1 @@
1
- {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,OAAO,KAAK,EACV,2BAA2B,EAC3B,oBAAoB,EACpB,SAAS,EACT,QAAQ,EACR,cAAc,EACd,SAAS,EACV,MAAM,eAAe,CAAC;AAcvB;;;;;;GAMG;AACH,qBAAa,wBAAyB,SAAQ,SAAU,YAAW,2BAA2B;IAC5F,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,eAAe,CAAyC;IAChE,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,SAAS,CAAiB;IAElC;;;OAGG;IACG,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpD,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,MAAM;IAIR,OAAO,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAmDlG,UAAU,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAYxD,aAAa,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAYtF,OAAO,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,CAAC;IA+ClG,gBAAgB,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,cAAc,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAO/F,iBAAiB,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAO/D,mBAAmB,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAOzD,sBAAsB;IAkBpC,OAAO,CAAC,aAAa;IAMf,gBAAgB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAGvD"}
1
+ {"version":3,"file":"web.d.ts","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,OAAO,KAAK,EACV,2BAA2B,EAC3B,oBAAoB,EACpB,SAAS,EACT,QAAQ,EACR,cAAc,EACd,SAAS,EACV,MAAM,eAAe,CAAC;AAevB;;;;;;GAMG;AACH,qBAAa,wBAAyB,SAAQ,SAAU,YAAW,2BAA2B;IAC5F,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,eAAe,CAAyC;IAChE,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,SAAS,CAAiB;IAElC;;;OAGG;IACG,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAWpD,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,MAAM;IAOR,OAAO,CACX,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,CAAC;IAiE5E,UAAU,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAYxD,aAAa,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,CAAC;IAa3G,OAAO,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,CAAC;IA+ClG,gBAAgB,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,cAAc,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ/F,iBAAiB,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAO/D,mBAAmB,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAOzD,sBAAsB;IAkBpC,OAAO,CAAC,aAAa;IAMf,gBAAgB,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAGvD"}
package/dist/esm/web.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { WebPlugin } from '@capacitor/core';
2
2
  import { sqlite3Worker1Promiser } from '@sqlite.org/sqlite-wasm';
3
+ import { assertSupportedIsolation } from './transaction-isolation';
3
4
  /**
4
5
  * Web implementation using the official SQLite Wasm build with OPFS persistence.
5
6
  *
@@ -20,7 +21,13 @@ export class CapgoCapacitorFastSqlWeb extends WebPlugin {
20
21
  * Must be called before connect() when overriding the default worker.
21
22
  */
22
23
  async configureWeb(config) {
23
- this.webConfig = config;
24
+ if (this.promiserPromise || this.databases.size > 0) {
25
+ throw new Error('Configure web storage before opening the first database');
26
+ }
27
+ if (config.requirePersistence && config.useOpfs === false) {
28
+ throw new Error('requirePersistence requires OPFS');
29
+ }
30
+ this.webConfig = Object.assign({}, config);
24
31
  this.promiserPromise = null;
25
32
  }
26
33
  getPromiser() {
@@ -31,28 +38,37 @@ export class CapgoCapacitorFastSqlWeb extends WebPlugin {
31
38
  return this.promiserPromise;
32
39
  }
33
40
  dbPath(database) {
41
+ if (!database || database === '.' || database === '..' || /[/\\\0]/.test(database)) {
42
+ throw new Error('Database must be a non-empty file name without path separators');
43
+ }
34
44
  return `/capgo-fast-sql/${database}.sqlite3`;
35
45
  }
36
46
  async connect(options) {
47
+ if (options.readOnly) {
48
+ throw new Error('Read-only opens are not supported by the SQLite Wasm Worker transport');
49
+ }
37
50
  if (this.databases.has(options.database)) {
38
51
  const existing = this.databases.get(options.database);
39
52
  return {
40
53
  port: existing.port,
41
54
  token: existing.token,
42
55
  database: options.database,
56
+ persistent: existing.persistent,
43
57
  };
44
58
  }
45
- const promiser = await this.getPromiser();
46
59
  const path = this.dbPath(options.database);
60
+ const promiser = await this.getPromiser();
47
61
  const useOpfs = this.webConfig.useOpfs !== false;
48
62
  let openResult;
49
63
  if (useOpfs) {
50
64
  try {
51
65
  openResult = await promiser('open', {
52
- filename: `file:${path}?vfs=opfs`,
66
+ filename: `file:/capgo-fast-sql/${encodeURIComponent(options.database)}.sqlite3?vfs=opfs`,
53
67
  });
54
68
  }
55
69
  catch (opfsError) {
70
+ if (this.webConfig.requirePersistence)
71
+ throw opfsError;
56
72
  console.warn('[CapgoCapacitorFastSql] OPFS unavailable; web database will not persist across reloads. ' +
57
73
  'Serve with Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp.', opfsError);
58
74
  openResult = await promiser('open', { filename: path });
@@ -66,7 +82,16 @@ export class CapgoCapacitorFastSqlWeb extends WebPlugin {
66
82
  if (!dbId) {
67
83
  throw new Error('Failed to open SQLite Wasm database: missing dbId');
68
84
  }
69
- await this.applyPerformanceConfig(promiser, dbId, options);
85
+ try {
86
+ if (this.webConfig.requirePersistence && !persistent) {
87
+ throw new Error('SQLite Worker did not confirm persistent storage');
88
+ }
89
+ await this.applyPerformanceConfig(promiser, dbId, options);
90
+ }
91
+ catch (error) {
92
+ await promiser({ type: 'close', dbId, args: {} });
93
+ throw error;
94
+ }
70
95
  const token = this.generateToken();
71
96
  const port = this.nextPort++;
72
97
  this.databases.set(options.database, { dbId, token, port, persistent });
@@ -74,6 +99,7 @@ export class CapgoCapacitorFastSqlWeb extends WebPlugin {
74
99
  port,
75
100
  token,
76
101
  database: options.database,
102
+ persistent,
77
103
  };
78
104
  }
79
105
  async disconnect(options) {
@@ -94,6 +120,7 @@ export class CapgoCapacitorFastSqlWeb extends WebPlugin {
94
120
  return {
95
121
  port: dbInfo.port,
96
122
  token: dbInfo.token,
123
+ persistent: dbInfo.persistent,
97
124
  };
98
125
  }
99
126
  async execute(options) {
@@ -141,6 +168,7 @@ export class CapgoCapacitorFastSqlWeb extends WebPlugin {
141
168
  }
142
169
  }
143
170
  async beginTransaction(options) {
171
+ assertSupportedIsolation(options.isolationLevel);
144
172
  await this.execute({
145
173
  database: options.database,
146
174
  statement: 'BEGIN TRANSACTION',
@@ -4,7 +4,9 @@ var core = require('@capacitor/core');
4
4
  var sqliteWasm = require('@sqlite.org/sqlite-wasm');
5
5
 
6
6
  /**
7
- * Transaction isolation levels
7
+ * Transaction isolation levels. Only Serializable is supported by the current
8
+ * SQLite backends. Other values are retained for source compatibility but reject
9
+ * before starting a transaction; they are not silently mapped to another level.
8
10
  */
9
11
  exports.IsolationLevel = void 0;
10
12
  (function (IsolationLevel) {
@@ -18,6 +20,12 @@ const CapgoCapacitorFastSql = core.registerPlugin('CapgoCapacitorFastSql', {
18
20
  web: () => Promise.resolve().then(function () { return web; }).then((m) => new m.CapgoCapacitorFastSqlWeb()),
19
21
  });
20
22
 
23
+ function assertSupportedIsolation(level) {
24
+ if (level !== undefined && level !== exports.IsolationLevel.Serializable) {
25
+ throw new Error('Only SERIALIZABLE transaction isolation is supported');
26
+ }
27
+ }
28
+
21
29
  /**
22
30
  * SQL Connection class that uses HTTP protocol for efficient communication
23
31
  * with native SQLite databases, bypassing Capacitor's standard bridge.
@@ -30,7 +38,12 @@ class NativeSQLConnection {
30
38
  this.database = database;
31
39
  this.port = port;
32
40
  this.token = token;
33
- this.baseUrl = `http://localhost:${port}`;
41
+ this.baseUrl = `http://127.0.0.1:${port}`;
42
+ }
43
+ browserFetch(input, init) {
44
+ const savedFetch = Reflect.get(globalThis, 'CapacitorWebFetch');
45
+ const browserFetch = typeof savedFetch === 'function' ? savedFetch : globalThis.fetch;
46
+ return browserFetch.call(globalThis, input, init);
34
47
  }
35
48
  /**
36
49
  * Get the database name
@@ -46,7 +59,7 @@ class NativeSQLConnection {
46
59
  * @returns Query results
47
60
  */
48
61
  async execute(statement, params) {
49
- const response = await fetch(`${this.baseUrl}/execute`, {
62
+ const response = await this.browserFetch(`${this.baseUrl}/execute`, {
50
63
  method: 'POST',
51
64
  headers: {
52
65
  'Content-Type': 'application/json',
@@ -72,7 +85,7 @@ class NativeSQLConnection {
72
85
  * @returns Array of results for each operation
73
86
  */
74
87
  async executeBatch(operations) {
75
- const response = await fetch(`${this.baseUrl}/batch`, {
88
+ const response = await this.browserFetch(`${this.baseUrl}/batch`, {
76
89
  method: 'POST',
77
90
  headers: {
78
91
  'Content-Type': 'application/json',
@@ -99,10 +112,11 @@ class NativeSQLConnection {
99
112
  * @param isolationLevel - Optional isolation level
100
113
  */
101
114
  async beginTransaction(isolationLevel) {
115
+ assertSupportedIsolation(isolationLevel);
102
116
  if (this.inTransaction) {
103
117
  throw new Error('Transaction already in progress');
104
118
  }
105
- const response = await fetch(`${this.baseUrl}/transaction/begin`, {
119
+ const response = await this.browserFetch(`${this.baseUrl}/transaction/begin`, {
106
120
  method: 'POST',
107
121
  headers: {
108
122
  'Content-Type': 'application/json',
@@ -126,7 +140,7 @@ class NativeSQLConnection {
126
140
  if (!this.inTransaction) {
127
141
  throw new Error('No transaction in progress');
128
142
  }
129
- const response = await fetch(`${this.baseUrl}/transaction/commit`, {
143
+ const response = await this.browserFetch(`${this.baseUrl}/transaction/commit`, {
130
144
  method: 'POST',
131
145
  headers: {
132
146
  Authorization: `Bearer ${this.token}`,
@@ -146,7 +160,7 @@ class NativeSQLConnection {
146
160
  if (!this.inTransaction) {
147
161
  throw new Error('No transaction in progress');
148
162
  }
149
- const response = await fetch(`${this.baseUrl}/transaction/rollback`, {
163
+ const response = await this.browserFetch(`${this.baseUrl}/transaction/rollback`, {
150
164
  method: 'POST',
151
165
  headers: {
152
166
  Authorization: `Bearer ${this.token}`,
@@ -307,6 +321,7 @@ class WebSQLConnection {
307
321
  * @param isolationLevel - Optional isolation level
308
322
  */
309
323
  async beginTransaction(isolationLevel) {
324
+ assertSupportedIsolation(isolationLevel);
310
325
  if (this.inTransaction) {
311
326
  throw new Error('Transaction already in progress');
312
327
  }
@@ -401,12 +416,40 @@ class FastSQL {
401
416
  * @returns SQLConnection instance for executing queries
402
417
  */
403
418
  static async connect(options) {
404
- // Check if already connected
405
- const existing = this.connections.get(options.database);
419
+ var _a;
420
+ const saved = this.openOptions.get(options.database);
421
+ if (saved && !this.optionsMatch(saved, options)) {
422
+ throw new Error(`Database '${options.database}' is already opening or open with different options`);
423
+ }
424
+ const existing = (_a = this.connections.get(options.database)) !== null && _a !== void 0 ? _a : this.opening.get(options.database);
406
425
  if (existing) {
407
426
  this.sharedConnections.add(options.database);
408
427
  return existing;
409
428
  }
429
+ const snapshot = Object.assign({}, options);
430
+ this.openOptions.set(options.database, snapshot);
431
+ const pending = this.open(snapshot);
432
+ this.opening.set(options.database, pending);
433
+ try {
434
+ return await pending;
435
+ }
436
+ catch (error) {
437
+ this.openOptions.delete(options.database);
438
+ this.sharedConnections.delete(options.database);
439
+ throw error;
440
+ }
441
+ finally {
442
+ this.opening.delete(options.database);
443
+ }
444
+ }
445
+ static optionsMatch(left, right) {
446
+ return (Boolean(left.encrypted) === Boolean(right.encrypted) &&
447
+ left.encryptionKey === right.encryptionKey &&
448
+ Boolean(left.readOnly) === Boolean(right.readOnly) &&
449
+ Boolean(left.walMode) === Boolean(right.walMode) &&
450
+ Boolean(left.performancePresets) === Boolean(right.performancePresets));
451
+ }
452
+ static async open(options) {
410
453
  // Connect via native plugin
411
454
  const info = await CapgoCapacitorFastSql.connect(options);
412
455
  // Create connection instance appropriate for the current platform
@@ -429,6 +472,7 @@ class FastSQL {
429
472
  */
430
473
  static async disconnect(database) {
431
474
  var _a;
475
+ await this.opening.get(database);
432
476
  const connection = this.connections.get(database);
433
477
  if (!connection) {
434
478
  throw new Error(`Database '${database}' is not connected`);
@@ -441,6 +485,7 @@ class FastSQL {
441
485
  await CapgoCapacitorFastSql.disconnect({ database });
442
486
  // Remove connection
443
487
  this.connections.delete(database);
488
+ this.openOptions.delete(database);
444
489
  this.sharedConnections.delete(database);
445
490
  this.connectionRetainers.delete(database);
446
491
  this.pendingDisconnects.delete(database);
@@ -492,7 +537,7 @@ class FastSQL {
492
537
  * Close all open connections
493
538
  */
494
539
  static async disconnectAll() {
495
- const databases = Array.from(this.connections.keys());
540
+ const databases = Array.from(new Set([...this.connections.keys(), ...this.opening.keys()]));
496
541
  await Promise.all(databases.map((db) => {
497
542
  this.connectionRetainers.delete(db);
498
543
  this.pendingDisconnects.delete(db);
@@ -508,6 +553,8 @@ class FastSQL {
508
553
  return Array.from(this.connections.keys());
509
554
  }
510
555
  }
556
+ FastSQL.opening = new Map();
557
+ FastSQL.openOptions = new Map();
511
558
  FastSQL.connections = new Map();
512
559
  FastSQL.sharedConnections = new Set();
513
560
  FastSQL.connectionRetainers = new Map();
@@ -859,8 +906,11 @@ class FastSQLVectorStore {
859
906
  .map((row) => this.rowToGetResult(row))
860
907
  .filter(params.predicate)
861
908
  .map((row) => row.id);
862
- for (const id of ids) {
863
- await this.connection.run(`DELETE FROM ${VECTOR_TABLE} WHERE store = ? AND id = ?`, [this.store, id]);
909
+ for (let offset = 0; offset < ids.length; offset += 100) {
910
+ await this.connection.executeBatch(ids.slice(offset, offset + 100).map((id) => ({
911
+ statement: `DELETE FROM ${VECTOR_TABLE} WHERE store = ? AND id = ?`,
912
+ params: [this.store, id],
913
+ })));
864
914
  }
865
915
  }
866
916
  async query(params) {
@@ -1093,7 +1143,13 @@ class CapgoCapacitorFastSqlWeb extends core.WebPlugin {
1093
1143
  * Must be called before connect() when overriding the default worker.
1094
1144
  */
1095
1145
  async configureWeb(config) {
1096
- this.webConfig = config;
1146
+ if (this.promiserPromise || this.databases.size > 0) {
1147
+ throw new Error('Configure web storage before opening the first database');
1148
+ }
1149
+ if (config.requirePersistence && config.useOpfs === false) {
1150
+ throw new Error('requirePersistence requires OPFS');
1151
+ }
1152
+ this.webConfig = Object.assign({}, config);
1097
1153
  this.promiserPromise = null;
1098
1154
  }
1099
1155
  getPromiser() {
@@ -1104,28 +1160,37 @@ class CapgoCapacitorFastSqlWeb extends core.WebPlugin {
1104
1160
  return this.promiserPromise;
1105
1161
  }
1106
1162
  dbPath(database) {
1163
+ if (!database || database === '.' || database === '..' || /[/\\\0]/.test(database)) {
1164
+ throw new Error('Database must be a non-empty file name without path separators');
1165
+ }
1107
1166
  return `/capgo-fast-sql/${database}.sqlite3`;
1108
1167
  }
1109
1168
  async connect(options) {
1169
+ if (options.readOnly) {
1170
+ throw new Error('Read-only opens are not supported by the SQLite Wasm Worker transport');
1171
+ }
1110
1172
  if (this.databases.has(options.database)) {
1111
1173
  const existing = this.databases.get(options.database);
1112
1174
  return {
1113
1175
  port: existing.port,
1114
1176
  token: existing.token,
1115
1177
  database: options.database,
1178
+ persistent: existing.persistent,
1116
1179
  };
1117
1180
  }
1118
- const promiser = await this.getPromiser();
1119
1181
  const path = this.dbPath(options.database);
1182
+ const promiser = await this.getPromiser();
1120
1183
  const useOpfs = this.webConfig.useOpfs !== false;
1121
1184
  let openResult;
1122
1185
  if (useOpfs) {
1123
1186
  try {
1124
1187
  openResult = await promiser('open', {
1125
- filename: `file:${path}?vfs=opfs`,
1188
+ filename: `file:/capgo-fast-sql/${encodeURIComponent(options.database)}.sqlite3?vfs=opfs`,
1126
1189
  });
1127
1190
  }
1128
1191
  catch (opfsError) {
1192
+ if (this.webConfig.requirePersistence)
1193
+ throw opfsError;
1129
1194
  console.warn('[CapgoCapacitorFastSql] OPFS unavailable; web database will not persist across reloads. ' +
1130
1195
  'Serve with Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp.', opfsError);
1131
1196
  openResult = await promiser('open', { filename: path });
@@ -1139,7 +1204,16 @@ class CapgoCapacitorFastSqlWeb extends core.WebPlugin {
1139
1204
  if (!dbId) {
1140
1205
  throw new Error('Failed to open SQLite Wasm database: missing dbId');
1141
1206
  }
1142
- await this.applyPerformanceConfig(promiser, dbId, options);
1207
+ try {
1208
+ if (this.webConfig.requirePersistence && !persistent) {
1209
+ throw new Error('SQLite Worker did not confirm persistent storage');
1210
+ }
1211
+ await this.applyPerformanceConfig(promiser, dbId, options);
1212
+ }
1213
+ catch (error) {
1214
+ await promiser({ type: 'close', dbId, args: {} });
1215
+ throw error;
1216
+ }
1143
1217
  const token = this.generateToken();
1144
1218
  const port = this.nextPort++;
1145
1219
  this.databases.set(options.database, { dbId, token, port, persistent });
@@ -1147,6 +1221,7 @@ class CapgoCapacitorFastSqlWeb extends core.WebPlugin {
1147
1221
  port,
1148
1222
  token,
1149
1223
  database: options.database,
1224
+ persistent,
1150
1225
  };
1151
1226
  }
1152
1227
  async disconnect(options) {
@@ -1167,6 +1242,7 @@ class CapgoCapacitorFastSqlWeb extends core.WebPlugin {
1167
1242
  return {
1168
1243
  port: dbInfo.port,
1169
1244
  token: dbInfo.token,
1245
+ persistent: dbInfo.persistent,
1170
1246
  };
1171
1247
  }
1172
1248
  async execute(options) {
@@ -1214,6 +1290,7 @@ class CapgoCapacitorFastSqlWeb extends core.WebPlugin {
1214
1290
  }
1215
1291
  }
1216
1292
  async beginTransaction(options) {
1293
+ assertSupportedIsolation(options.isolationLevel);
1217
1294
  await this.execute({
1218
1295
  database: options.database,
1219
1296
  statement: 'BEGIN TRANSACTION',