@powersync/op-sqlite 0.0.0-dev-20250528152729 → 0.0.0-dev-20250604135557
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 +10 -5
- package/lib/commonjs/db/OPSqliteAdapter.js +45 -9
- package/lib/commonjs/db/OPSqliteAdapter.js.map +1 -1
- package/lib/commonjs/db/SqliteOptions.js +10 -1
- package/lib/commonjs/db/SqliteOptions.js.map +1 -1
- package/lib/commonjs/index.js +16 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/db/OPSqliteAdapter.js +45 -9
- package/lib/module/db/OPSqliteAdapter.js.map +1 -1
- package/lib/module/db/SqliteOptions.js +9 -0
- package/lib/module/db/SqliteOptions.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/commonjs/src/db/OPSqliteAdapter.d.ts +9 -1
- package/lib/typescript/commonjs/src/db/OPSqliteAdapter.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/db/SqliteOptions.d.ts +16 -0
- package/lib/typescript/commonjs/src/db/SqliteOptions.d.ts.map +1 -1
- package/lib/typescript/commonjs/src/index.d.ts +1 -0
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/tsconfig.build.tsbuildinfo +1 -1
- package/lib/typescript/module/src/db/OPSqliteAdapter.d.ts +9 -1
- package/lib/typescript/module/src/db/OPSqliteAdapter.d.ts.map +1 -1
- package/lib/typescript/module/src/db/SqliteOptions.d.ts +16 -0
- package/lib/typescript/module/src/db/SqliteOptions.d.ts.map +1 -1
- package/lib/typescript/module/src/index.d.ts +1 -0
- package/lib/typescript/module/src/index.d.ts.map +1 -1
- package/lib/typescript/module/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/db/OPSqliteAdapter.ts +61 -10
- package/src/db/SqliteOptions.ts +19 -0
- package/src/index.ts +3 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@powersync/op-sqlite",
|
|
3
|
-
"version": "0.0.0-dev-
|
|
3
|
+
"version": "0.0.0-dev-20250604135557",
|
|
4
4
|
"description": "PowerSync - sync Postgres or MongoDB with SQLite in your React Native app for offline-first and real-time data",
|
|
5
5
|
"source": "./src/index.ts",
|
|
6
6
|
"main": "./lib/commonjs/index.js",
|
|
@@ -58,17 +58,17 @@
|
|
|
58
58
|
"access": "public"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
|
-
"@op-engineering/op-sqlite": "^
|
|
62
|
-
"@powersync/common": "
|
|
61
|
+
"@op-engineering/op-sqlite": "^13.0.0 || ^14.0.0",
|
|
62
|
+
"@powersync/common": "^1.31.1",
|
|
63
63
|
"react": "*",
|
|
64
64
|
"react-native": "*"
|
|
65
65
|
},
|
|
66
66
|
"dependencies": {
|
|
67
67
|
"async-lock": "^1.4.0",
|
|
68
|
-
"@powersync/common": "
|
|
68
|
+
"@powersync/common": "1.31.1"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@op-engineering/op-sqlite": "^
|
|
71
|
+
"@op-engineering/op-sqlite": "^14.0.2",
|
|
72
72
|
"@react-native/eslint-config": "^0.73.1",
|
|
73
73
|
"@types/async-lock": "^1.4.0",
|
|
74
74
|
"@types/react": "^18.2.44",
|
|
@@ -3,7 +3,7 @@ import { BaseObserver, DBAdapter, DBAdapterListener, DBLockOptions, QueryResult,
|
|
|
3
3
|
import Lock from 'async-lock';
|
|
4
4
|
import { Platform } from 'react-native';
|
|
5
5
|
import { OPSQLiteConnection } from './OPSQLiteConnection';
|
|
6
|
-
import { SqliteOptions } from './SqliteOptions';
|
|
6
|
+
import { CipherVersion, SqliteOptions } from './SqliteOptions';
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Adapter for React Native Quick SQLite
|
|
@@ -50,7 +50,7 @@ export class OPSQLiteDBAdapter extends BaseObserver<DBAdapterListener> implement
|
|
|
50
50
|
this.options.sqliteOptions!;
|
|
51
51
|
const dbFilename = this.options.name;
|
|
52
52
|
|
|
53
|
-
this.writeConnection = await this.openConnection(dbFilename);
|
|
53
|
+
this.writeConnection = await this.openConnection(dbFilename, true);
|
|
54
54
|
|
|
55
55
|
const baseStatements = [
|
|
56
56
|
`PRAGMA busy_timeout = ${lockTimeoutMs}`,
|
|
@@ -97,9 +97,13 @@ export class OPSQLiteDBAdapter extends BaseObserver<DBAdapterListener> implement
|
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
-
protected async openConnection(filenameOverride?: string): Promise<OPSQLiteConnection> {
|
|
100
|
+
protected async openConnection(filenameOverride?: string, writeConnection?: boolean): Promise<OPSQLiteConnection> {
|
|
101
101
|
const dbFilename = filenameOverride ?? this.options.name;
|
|
102
|
-
const DB: DB = this.openDatabase(
|
|
102
|
+
const DB: DB = await this.openDatabase(
|
|
103
|
+
dbFilename,
|
|
104
|
+
this.options.sqliteOptions?.encryptionKey ?? undefined,
|
|
105
|
+
writeConnection
|
|
106
|
+
);
|
|
103
107
|
|
|
104
108
|
//Load extensions for all connections
|
|
105
109
|
this.loadAdditionalExtensions(DB);
|
|
@@ -120,16 +124,12 @@ export class OPSQLiteDBAdapter extends BaseObserver<DBAdapterListener> implement
|
|
|
120
124
|
}
|
|
121
125
|
}
|
|
122
126
|
|
|
123
|
-
private openDatabase(dbFilename: string, encryptionKey?: string): DB {
|
|
127
|
+
private async openDatabase(dbFilename: string, encryptionKey?: string, writeConnection?: boolean): Promise<DB> {
|
|
124
128
|
//This is needed because an undefined/null dbLocation will cause the open function to fail
|
|
125
129
|
const location = this.getDbLocation(this.options.dbLocation);
|
|
126
130
|
//Simarlily if the encryption key is undefined/null when using SQLCipher it will cause the open function to fail
|
|
127
131
|
if (encryptionKey) {
|
|
128
|
-
return
|
|
129
|
-
name: dbFilename,
|
|
130
|
-
location: location,
|
|
131
|
-
encryptionKey: encryptionKey
|
|
132
|
-
});
|
|
132
|
+
return await this.openSQLCipher(dbFilename, location, encryptionKey, writeConnection);
|
|
133
133
|
} else {
|
|
134
134
|
return open({
|
|
135
135
|
name: dbFilename,
|
|
@@ -138,6 +138,57 @@ export class OPSQLiteDBAdapter extends BaseObserver<DBAdapterListener> implement
|
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
+
/**
|
|
142
|
+
* We set up SQLCipher compatibility here.
|
|
143
|
+
*
|
|
144
|
+
* - For compability with SQLCipher 3 databases, we set the cipher_compatibility pragma to 3 for all connections.
|
|
145
|
+
* - For upgrading SQLCipher 3 databases to version 4, we do the migration on the write connection.
|
|
146
|
+
* - For SQLCipher 4 databases, we do not need to set the cipher_compatibility pragma, as it is the default.
|
|
147
|
+
*/
|
|
148
|
+
private async openSQLCipher(
|
|
149
|
+
dbFilename: string,
|
|
150
|
+
location: string,
|
|
151
|
+
encryptionKey?: string,
|
|
152
|
+
writeConnection?: boolean
|
|
153
|
+
): Promise<DB> {
|
|
154
|
+
const openDb = () =>
|
|
155
|
+
open({
|
|
156
|
+
name: dbFilename,
|
|
157
|
+
location: location,
|
|
158
|
+
encryptionKey: encryptionKey
|
|
159
|
+
});
|
|
160
|
+
const db = openDb();
|
|
161
|
+
|
|
162
|
+
const cipherVersion = this.options.sqliteOptions?.cipherVersion;
|
|
163
|
+
|
|
164
|
+
if (cipherVersion == CipherVersion.VERSION_3) {
|
|
165
|
+
await db.execute('PRAGMA cipher_compatibility = 3;');
|
|
166
|
+
return db;
|
|
167
|
+
} else if (cipherVersion == CipherVersion.UPGRADE_3_TO_4 && writeConnection) {
|
|
168
|
+
// Based on steps described at https://www.zetetic.net/sqlcipher/sqlcipher-api/#cipher_migrate
|
|
169
|
+
try {
|
|
170
|
+
// Valid version agnostic query to confirm SQLCipher version
|
|
171
|
+
await db.execute('SELECT count(*) FROM sqlite_master;');
|
|
172
|
+
// Query succeeded, so we are on SQLCipher 4 and don't have to do anything
|
|
173
|
+
console.log('SQLCipher 4 database detected, no migration needed.');
|
|
174
|
+
return db;
|
|
175
|
+
} catch (e: any) {
|
|
176
|
+
// Query failed, assuming we are on SQLCipher 3 and need to upgrade
|
|
177
|
+
// Catch any error
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
db.close();
|
|
181
|
+
const reopenedDB = openDb();
|
|
182
|
+
|
|
183
|
+
const migrationResult = await reopenedDB.execute('PRAGMA cipher_migrate;');
|
|
184
|
+
console.log('SQLCipher migration result:', migrationResult);
|
|
185
|
+
|
|
186
|
+
return reopenedDB;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return db;
|
|
190
|
+
}
|
|
191
|
+
|
|
141
192
|
private loadAdditionalExtensions(DB: DB) {
|
|
142
193
|
if (this.options.sqliteOptions?.extensions && this.options.sqliteOptions.extensions.length > 0) {
|
|
143
194
|
for (const extension of this.options.sqliteOptions.extensions) {
|
package/src/db/SqliteOptions.ts
CHANGED
|
@@ -30,6 +30,18 @@ export interface SqliteOptions {
|
|
|
30
30
|
*/
|
|
31
31
|
encryptionKey?: string | null;
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* SQLCipher version compatibility option. Only applicable when encryptionKey is set.
|
|
35
|
+
*
|
|
36
|
+
* - '4': Use SQLCipher 4 format (recommended for new databases)
|
|
37
|
+
* - 'upgrade3to4': Automatically attempt to upgrade SQLCipher 3 databases to version 4
|
|
38
|
+
* - '3': Use SQLCipher 3 compatibility mode for existing databases (used by default)
|
|
39
|
+
*
|
|
40
|
+
* Note: The 'upgrade3to4' option will attempt migration only when needed and may
|
|
41
|
+
* be expensive on first run. Migration requires the correct encryption key.
|
|
42
|
+
*/
|
|
43
|
+
cipherVersion?: CipherVersion | null;
|
|
44
|
+
|
|
33
45
|
/**
|
|
34
46
|
* Where to store SQLite temporary files. Defaults to 'MEMORY'.
|
|
35
47
|
* Setting this to `FILESYSTEM` can cause issues with larger queries or datasets.
|
|
@@ -55,6 +67,12 @@ export interface SqliteOptions {
|
|
|
55
67
|
}>;
|
|
56
68
|
}
|
|
57
69
|
|
|
70
|
+
export enum CipherVersion {
|
|
71
|
+
VERSION_4 = '4',
|
|
72
|
+
UPGRADE_3_TO_4 = 'upgrade3to4',
|
|
73
|
+
VERSION_3 = '3'
|
|
74
|
+
}
|
|
75
|
+
|
|
58
76
|
export enum TemporaryStorageOption {
|
|
59
77
|
MEMORY = 'memory',
|
|
60
78
|
FILESYSTEM = 'file'
|
|
@@ -89,5 +107,6 @@ export const DEFAULT_SQLITE_OPTIONS: Required<SqliteOptions> = {
|
|
|
89
107
|
temporaryStorage: TemporaryStorageOption.MEMORY,
|
|
90
108
|
lockTimeoutMs: 30000,
|
|
91
109
|
encryptionKey: null,
|
|
110
|
+
cipherVersion: CipherVersion.VERSION_3,
|
|
92
111
|
extensions: []
|
|
93
112
|
};
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
} from './db/OPSqliteDBOpenFactory';
|
|
1
|
+
export { OPSqliteOpenFactory, OPSQLiteOpenFactoryOptions } from './db/OPSqliteDBOpenFactory';
|
|
2
|
+
|
|
3
|
+
export * from './db/SqliteOptions';
|