@powersync/op-sqlite 0.0.0-dev-20250121082529 → 0.0.0-dev-20250121114305

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 (64) hide show
  1. package/lib/{typescript/commonjs/src → src}/db/OPSQLiteConnection.d.ts +0 -1
  2. package/lib/src/db/OPSQLiteConnection.js +118 -0
  3. package/lib/{typescript/module/src → src}/db/OPSqliteAdapter.d.ts +0 -1
  4. package/lib/src/db/OPSqliteAdapter.js +267 -0
  5. package/lib/{typescript/commonjs/src → src}/db/OPSqliteDBOpenFactory.d.ts +0 -1
  6. package/lib/src/db/OPSqliteDBOpenFactory.js +15 -0
  7. package/lib/{typescript/commonjs/src → src}/db/SqliteOptions.d.ts +1 -2
  8. package/lib/src/db/SqliteOptions.js +29 -0
  9. package/lib/{typescript/commonjs/src → src}/index.d.ts +0 -1
  10. package/lib/src/index.js +1 -0
  11. package/lib/tsconfig.tsbuildinfo +1 -0
  12. package/package.json +6 -75
  13. package/android/build.gradle +0 -124
  14. package/android/gradle.properties +0 -5
  15. package/android/src/main/AndroidManifest.xml +0 -3
  16. package/android/src/main/AndroidManifestNew.xml +0 -2
  17. package/android/src/main/java/com/powersync/opsqlite/PowerSyncOpSqlitePackage.kt +0 -31
  18. package/ios/PowerSyncOpSqlite.h +0 -5
  19. package/ios/PowerSyncOpSqlite.mm +0 -6
  20. package/lib/commonjs/db/OPSQLiteConnection.js +0 -103
  21. package/lib/commonjs/db/OPSQLiteConnection.js.map +0 -1
  22. package/lib/commonjs/db/OPSqliteAdapter.js +0 -249
  23. package/lib/commonjs/db/OPSqliteAdapter.js.map +0 -1
  24. package/lib/commonjs/db/OPSqliteDBOpenFactory.js +0 -26
  25. package/lib/commonjs/db/OPSqliteDBOpenFactory.js.map +0 -1
  26. package/lib/commonjs/db/SqliteOptions.js +0 -33
  27. package/lib/commonjs/db/SqliteOptions.js.map +0 -1
  28. package/lib/commonjs/index.js +0 -19
  29. package/lib/commonjs/index.js.map +0 -1
  30. package/lib/module/db/OPSQLiteConnection.js +0 -98
  31. package/lib/module/db/OPSQLiteConnection.js.map +0 -1
  32. package/lib/module/db/OPSqliteAdapter.js +0 -244
  33. package/lib/module/db/OPSqliteAdapter.js.map +0 -1
  34. package/lib/module/db/OPSqliteDBOpenFactory.js +0 -21
  35. package/lib/module/db/OPSqliteDBOpenFactory.js.map +0 -1
  36. package/lib/module/db/SqliteOptions.js +0 -29
  37. package/lib/module/db/SqliteOptions.js.map +0 -1
  38. package/lib/module/index.js +0 -4
  39. package/lib/module/index.js.map +0 -1
  40. package/lib/typescript/commonjs/package.json +0 -1
  41. package/lib/typescript/commonjs/src/db/OPSQLiteConnection.d.ts.map +0 -1
  42. package/lib/typescript/commonjs/src/db/OPSqliteAdapter.d.ts +0 -45
  43. package/lib/typescript/commonjs/src/db/OPSqliteAdapter.d.ts.map +0 -1
  44. package/lib/typescript/commonjs/src/db/OPSqliteDBOpenFactory.d.ts.map +0 -1
  45. package/lib/typescript/commonjs/src/db/SqliteOptions.d.ts.map +0 -1
  46. package/lib/typescript/commonjs/src/index.d.ts.map +0 -1
  47. package/lib/typescript/commonjs/tsconfig.build.tsbuildinfo +0 -1
  48. package/lib/typescript/module/package.json +0 -1
  49. package/lib/typescript/module/src/db/OPSQLiteConnection.d.ts +0 -27
  50. package/lib/typescript/module/src/db/OPSQLiteConnection.d.ts.map +0 -1
  51. package/lib/typescript/module/src/db/OPSqliteAdapter.d.ts.map +0 -1
  52. package/lib/typescript/module/src/db/OPSqliteDBOpenFactory.d.ts +0 -12
  53. package/lib/typescript/module/src/db/OPSqliteDBOpenFactory.d.ts.map +0 -1
  54. package/lib/typescript/module/src/db/SqliteOptions.d.ts +0 -52
  55. package/lib/typescript/module/src/db/SqliteOptions.d.ts.map +0 -1
  56. package/lib/typescript/module/src/index.d.ts +0 -2
  57. package/lib/typescript/module/src/index.d.ts.map +0 -1
  58. package/lib/typescript/module/tsconfig.build.tsbuildinfo +0 -1
  59. package/powersync-op-sqlite.podspec +0 -26
  60. package/src/db/OPSQLiteConnection.ts +0 -131
  61. package/src/db/OPSqliteAdapter.ts +0 -299
  62. package/src/db/OPSqliteDBOpenFactory.ts +0 -25
  63. package/src/db/SqliteOptions.ts +0 -71
  64. package/src/index.ts +0 -4
@@ -1,299 +0,0 @@
1
- import {
2
- BaseObserver,
3
- DBAdapter,
4
- DBAdapterListener,
5
- DBLockOptions,
6
- QueryResult,
7
- Transaction
8
- } from '@powersync/common';
9
- import {
10
- ANDROID_DATABASE_PATH,
11
- getDylibPath,
12
- IOS_LIBRARY_PATH,
13
- open,
14
- type DB
15
- } from '@op-engineering/op-sqlite';
16
- import Lock from 'async-lock';
17
- import { OPSQLiteConnection } from './OPSQLiteConnection';
18
- import { Platform } from 'react-native';
19
- import { SqliteOptions } from './SqliteOptions';
20
-
21
- /**
22
- * Adapter for React Native Quick SQLite
23
- */
24
- export type OPSQLiteAdapterOptions = {
25
- name: string;
26
- dbLocation?: string;
27
- sqliteOptions?: SqliteOptions;
28
- };
29
-
30
- enum LockType {
31
- READ = 'read',
32
- WRITE = 'write'
33
- }
34
-
35
- const READ_CONNECTIONS = 5;
36
-
37
- export class OPSQLiteDBAdapter extends BaseObserver<DBAdapterListener> implements DBAdapter {
38
- name: string;
39
- protected locks: Lock;
40
-
41
- protected initialized: Promise<void>;
42
-
43
- protected readConnections: Array<{ busy: boolean; connection: OPSQLiteConnection }> | null;
44
-
45
- protected writeConnection: OPSQLiteConnection | null;
46
-
47
- private readQueue: Array<() => void> = [];
48
-
49
- constructor(protected options: OPSQLiteAdapterOptions) {
50
- super();
51
- this.name = this.options.name;
52
-
53
- this.locks = new Lock();
54
- this.readConnections = null;
55
- this.writeConnection = null;
56
- this.initialized = this.init();
57
- }
58
-
59
- protected async init() {
60
- const { lockTimeoutMs, journalMode, journalSizeLimit, synchronous, encryptionKey } = this.options.sqliteOptions;
61
- const dbFilename = this.options.name;
62
-
63
- this.writeConnection = await this.openConnection(dbFilename);
64
-
65
- const statements: string[] = [
66
- `PRAGMA busy_timeout = ${lockTimeoutMs}`,
67
- `PRAGMA journal_mode = ${journalMode}`,
68
- `PRAGMA journal_size_limit = ${journalSizeLimit}`,
69
- `PRAGMA synchronous = ${synchronous}`
70
- ];
71
-
72
- for (const statement of statements) {
73
- for (let tries = 0; tries < 30; tries++) {
74
- try {
75
- await this.writeConnection!.execute(statement);
76
- break;
77
- } catch (e: any) {
78
- if (e instanceof Error && e.message.includes('database is locked') && tries < 29) {
79
- continue;
80
- } else {
81
- throw e;
82
- }
83
- }
84
- }
85
- }
86
-
87
- // Changes should only occur in the write connection
88
- this.writeConnection!.registerListener({
89
- tablesUpdated: (notification) => this.iterateListeners((cb) => cb.tablesUpdated?.(notification))
90
- });
91
-
92
- this.readConnections = [];
93
- for (let i = 0; i < READ_CONNECTIONS; i++) {
94
- const conn = await this.openConnection(dbFilename);
95
- await conn.execute('PRAGMA query_only = true');
96
- this.readConnections.push({ busy: false, connection: conn });
97
- }
98
- }
99
-
100
- protected async openConnection(filenameOverride?: string): Promise<OPSQLiteConnection> {
101
- const dbFilename = filenameOverride ?? this.options.name;
102
- const DB: DB = this.openDatabase(dbFilename, this.options.sqliteOptions.encryptionKey);
103
-
104
- //Load extensions for all connections
105
- this.loadAdditionalExtensions(DB);
106
- this.loadPowerSyncExtension(DB);
107
-
108
- await DB.execute('SELECT powersync_init()');
109
-
110
- return new OPSQLiteConnection({
111
- baseDB: DB
112
- });
113
- }
114
-
115
- private getDbLocation(dbLocation?: string): string {
116
- if (Platform.OS === 'ios') {
117
- return dbLocation ?? IOS_LIBRARY_PATH;
118
- } else {
119
- return dbLocation ?? ANDROID_DATABASE_PATH;
120
- }
121
- }
122
-
123
- private openDatabase(dbFilename: string, encryptionKey?: string): DB {
124
- //This is needed because an undefined/null dbLocation will cause the open function to fail
125
- const location = this.getDbLocation(this.options.dbLocation);
126
- //Simarlily if the encryption key is undefined/null when using SQLCipher it will cause the open function to fail
127
- if (encryptionKey) {
128
- return open({
129
- name: dbFilename,
130
- location: location,
131
- encryptionKey: encryptionKey
132
- });
133
- } else {
134
- return open({
135
- name: dbFilename,
136
- location: location
137
- });
138
- }
139
- }
140
-
141
- private loadAdditionalExtensions(DB: DB) {
142
- if (this.options.sqliteOptions.extensions.length > 0) {
143
- for (const extension of this.options.sqliteOptions.extensions) {
144
- DB.loadExtension(extension.path, extension.entryPoint);
145
- }
146
- }
147
- }
148
-
149
- private async loadPowerSyncExtension(DB: DB) {
150
- if (Platform.OS === 'ios') {
151
- const libPath = getDylibPath('co.powersync.sqlitecore', 'powersync-sqlite-core');
152
- DB.loadExtension(libPath, 'sqlite3_powersync_init');
153
- } else {
154
- DB.loadExtension('libpowersync', 'sqlite3_powersync_init');
155
- }
156
- }
157
-
158
- close() {
159
- this.initialized.then(() => {
160
- this.writeConnection!.close();
161
- this.readConnections!.forEach((c) => c.connection.close());
162
- });
163
- }
164
-
165
- async readLock<T>(fn: (tx: OPSQLiteConnection) => Promise<T>, options?: DBLockOptions): Promise<T> {
166
- await this.initialized;
167
- return new Promise(async (resolve, reject) => {
168
- const execute = async () => {
169
- // Find an available connection that is not busy
170
- const availableConnection = this.readConnections!.find((conn) => !conn.busy);
171
-
172
- // If we have an available connection, use it
173
- if (availableConnection) {
174
- availableConnection.busy = true;
175
- try {
176
- resolve(await fn(availableConnection.connection));
177
- } catch (error) {
178
- reject(error);
179
- } finally {
180
- availableConnection.busy = false;
181
- // After query execution, process any queued tasks
182
- this.processQueue();
183
- }
184
- } else {
185
- // If no available connections, add to the queue
186
- this.readQueue.push(execute);
187
- }
188
- };
189
-
190
- execute();
191
- });
192
- }
193
-
194
- private async processQueue(): Promise<void> {
195
- if (this.readQueue.length > 0) {
196
- const next = this.readQueue.shift();
197
- if (next) {
198
- next();
199
- }
200
- }
201
- }
202
-
203
- async writeLock<T>(fn: (tx: OPSQLiteConnection) => Promise<T>, options?: DBLockOptions): Promise<T> {
204
- await this.initialized;
205
-
206
- return new Promise(async (resolve, reject) => {
207
- try {
208
- await this.locks
209
- .acquire(
210
- LockType.WRITE,
211
- async () => {
212
- resolve(await fn(this.writeConnection!));
213
- },
214
- { timeout: options?.timeoutMs }
215
- )
216
- .then(() => {
217
- // flush updates once a write lock has been released
218
- this.writeConnection!.flushUpdates();
219
- });
220
- } catch (ex) {
221
- reject(ex);
222
- }
223
- });
224
- }
225
-
226
- readTransaction<T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions): Promise<T> {
227
- return this.readLock((ctx) => this.internalTransaction(ctx, fn));
228
- }
229
-
230
- writeTransaction<T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions): Promise<T> {
231
- return this.writeLock((ctx) => this.internalTransaction(ctx, fn));
232
- }
233
-
234
- getAll<T>(sql: string, parameters?: any[]): Promise<T[]> {
235
- return this.readLock((ctx) => ctx.getAll(sql, parameters));
236
- }
237
-
238
- getOptional<T>(sql: string, parameters?: any[]): Promise<T | null> {
239
- return this.readLock((ctx) => ctx.getOptional(sql, parameters));
240
- }
241
-
242
- get<T>(sql: string, parameters?: any[]): Promise<T> {
243
- return this.readLock((ctx) => ctx.get(sql, parameters));
244
- }
245
-
246
- execute(query: string, params?: any[]) {
247
- return this.writeLock((ctx) => ctx.execute(query, params));
248
- }
249
-
250
- async executeBatch(query: string, params: any[][] = []): Promise<QueryResult> {
251
- return this.writeLock((ctx) => ctx.executeBatch(query, params));
252
- }
253
-
254
- protected async internalTransaction<T>(
255
- connection: OPSQLiteConnection,
256
- fn: (tx: Transaction) => Promise<T>
257
- ): Promise<T> {
258
- let finalized = false;
259
- const commit = async (): Promise<QueryResult> => {
260
- if (finalized) {
261
- return { rowsAffected: 0 };
262
- }
263
- finalized = true;
264
- return connection.execute('COMMIT');
265
- };
266
- const rollback = async (): Promise<QueryResult> => {
267
- if (finalized) {
268
- return { rowsAffected: 0 };
269
- }
270
- finalized = true;
271
- return connection.execute('ROLLBACK');
272
- };
273
- try {
274
- await connection.execute('BEGIN');
275
- const result = await fn({
276
- execute: (query, params) => connection.execute(query, params),
277
- get: (query, params) => connection.get(query, params),
278
- getAll: (query, params) => connection.getAll(query, params),
279
- getOptional: (query, params) => connection.getOptional(query, params),
280
- commit,
281
- rollback
282
- });
283
- await commit();
284
- return result;
285
- } catch (ex) {
286
- await rollback();
287
- throw ex;
288
- }
289
- }
290
-
291
- async refreshSchema(): Promise<void> {
292
- await this.initialized;
293
- await this.writeConnection!.refreshSchema();
294
-
295
- for (let readConnection of this.readConnections) {
296
- await readConnection.connection.refreshSchema();
297
- }
298
- }
299
- }
@@ -1,25 +0,0 @@
1
- import { DBAdapter, SQLOpenFactory, SQLOpenOptions } from '@powersync/common';
2
- import { OPSQLiteDBAdapter } from './OPSqliteAdapter';
3
- import { DEFAULT_SQLITE_OPTIONS, SqliteOptions } from './SqliteOptions';
4
-
5
- export interface OPSQLiteOpenFactoryOptions extends SQLOpenOptions {
6
- sqliteOptions?: SqliteOptions;
7
- }
8
- export class OPSqliteOpenFactory implements SQLOpenFactory {
9
- private sqliteOptions: Required<SqliteOptions>;
10
-
11
- constructor(protected options: OPSQLiteOpenFactoryOptions) {
12
- this.sqliteOptions = {
13
- ...DEFAULT_SQLITE_OPTIONS,
14
- ...this.options.sqliteOptions
15
- };
16
- }
17
-
18
- openDB(): DBAdapter {
19
- return new OPSQLiteDBAdapter({
20
- name: this.options.dbFilename,
21
- dbLocation: this.options.dbLocation,
22
- sqliteOptions: this.sqliteOptions
23
- });
24
- }
25
- }
@@ -1,71 +0,0 @@
1
- export interface SqliteOptions {
2
- /**
3
- * SQLite journal mode. Defaults to [SqliteJournalMode.wal].
4
- */
5
- journalMode?: SqliteJournalMode;
6
-
7
- /**
8
- * SQLite synchronous flag. Defaults to [SqliteSynchronous.normal], which
9
- * is safe for WAL mode.
10
- */
11
- synchronous?: SqliteSynchronous;
12
-
13
- /**
14
- * Journal/WAL size limit. Defaults to 6MB.
15
- * The WAL may grow larger than this limit during writes, but SQLite will
16
- * attempt to truncate the file afterwards.
17
- */
18
- journalSizeLimit?: number;
19
-
20
- /**
21
- * Timeout in milliseconds waiting for locks to be released by other connections.
22
- * Defaults to 30 seconds.
23
- * Set to null or zero to fail immediately when the database is locked.
24
- */
25
- lockTimeoutMs?: number;
26
-
27
- /**
28
- * Encryption key for the database.
29
- * If set, the database will be encrypted using SQLCipher.
30
- */
31
- encryptionKey?: string;
32
-
33
- /**
34
- * Load extensions using the path and entryPoint.
35
- * More info can be found here https://op-engineering.github.io/op-sqlite/docs/api#loading-extensions.
36
- */
37
- extensions?: Array<{
38
- path: string;
39
- entryPoint?: string;
40
- }>;
41
- }
42
-
43
- // SQLite journal mode. Set on the primary connection.
44
- // This library is written with WAL mode in mind - other modes may cause
45
- // unexpected locking behavior.
46
- enum SqliteJournalMode {
47
- // Use a write-ahead log instead of a rollback journal.
48
- // This provides good performance and concurrency.
49
- wal = 'WAL',
50
- delete = 'DELETE',
51
- truncate = 'TRUNCATE',
52
- persist = 'PERSIST',
53
- memory = 'MEMORY',
54
- off = 'OFF'
55
- }
56
-
57
- // SQLite file commit mode.
58
- enum SqliteSynchronous {
59
- normal = 'NORMAL',
60
- full = 'FULL',
61
- off = 'OFF'
62
- }
63
-
64
- export const DEFAULT_SQLITE_OPTIONS: Required<SqliteOptions> = {
65
- journalMode: SqliteJournalMode.wal,
66
- synchronous: SqliteSynchronous.normal,
67
- journalSizeLimit: 6 * 1024 * 1024,
68
- lockTimeoutMs: 30000,
69
- encryptionKey: null,
70
- extensions: []
71
- };
package/src/index.ts DELETED
@@ -1,4 +0,0 @@
1
- export {
2
- OPSqliteOpenFactory,
3
- OPSQLiteOpenFactoryOptions
4
- } from './db/OPSqliteDBOpenFactory';