@powersync/op-sqlite 0.0.5 → 0.0.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@powersync/op-sqlite",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
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",
@@ -59,13 +59,13 @@
59
59
  },
60
60
  "peerDependencies": {
61
61
  "@op-engineering/op-sqlite": "^9.2.1",
62
- "@powersync/common": "^1.20.1",
62
+ "@powersync/common": "^1.20.2",
63
63
  "react": "*",
64
64
  "react-native": "*"
65
65
  },
66
66
  "dependencies": {
67
67
  "async-lock": "^1.4.0",
68
- "@powersync/common": "1.20.1"
68
+ "@powersync/common": "1.20.2"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@op-engineering/op-sqlite": "^9.2.1",
@@ -35,10 +35,12 @@ export class OPSQLiteDBAdapter extends BaseObserver<DBAdapterListener> implement
35
35
 
36
36
  protected initialized: Promise<void>;
37
37
 
38
- protected readConnections: OPSQLiteConnection[] | null;
38
+ protected readConnections: Array<{ busy: boolean; connection: OPSQLiteConnection }> | null;
39
39
 
40
40
  protected writeConnection: OPSQLiteConnection | null;
41
41
 
42
+ private readQueue: Array<() => void> = [];
43
+
42
44
  constructor(protected options: OPSQLiteAdapterOptions) {
43
45
  super();
44
46
  this.name = this.options.name;
@@ -88,7 +90,7 @@ export class OPSQLiteDBAdapter extends BaseObserver<DBAdapterListener> implement
88
90
  let dbName = './'.repeat(i + 1) + dbFilename;
89
91
  const conn = await this.openConnection(dbName);
90
92
  await conn.execute('PRAGMA query_only = true');
91
- this.readConnections.push(conn);
93
+ this.readConnections.push({ busy: false, connection: conn });
92
94
  }
93
95
  }
94
96
 
@@ -145,36 +147,46 @@ export class OPSQLiteDBAdapter extends BaseObserver<DBAdapterListener> implement
145
147
  close() {
146
148
  this.initialized.then(() => {
147
149
  this.writeConnection!.close();
148
- this.readConnections!.forEach((c) => c.close());
150
+ this.readConnections!.forEach((c) => c.connection.close());
149
151
  });
150
152
  }
151
153
 
152
154
  async readLock<T>(fn: (tx: OPSQLiteConnection) => Promise<T>, options?: DBLockOptions): Promise<T> {
153
155
  await this.initialized;
154
- // TODO: Use async queues to handle multiple read connections
155
- const sortedConnections = this.readConnections!.map((connection, index) => ({
156
- lockKey: `${LockType.READ}-${index}`,
157
- connection
158
- })).sort((a, b) => {
159
- const aBusy = this.locks.isBusy(a.lockKey);
160
- const bBusy = this.locks.isBusy(b.lockKey);
161
- // Sort by ones which are not busy
162
- return aBusy > bBusy ? 1 : 0;
156
+ return new Promise(async (resolve, reject) => {
157
+ const execute = async () => {
158
+ // Find an available connection that is not busy
159
+ const availableConnection = this.readConnections!.find((conn) => !conn.busy);
160
+
161
+ // If we have an available connection, use it
162
+ if (availableConnection) {
163
+ availableConnection.busy = true;
164
+ try {
165
+ resolve(await fn(availableConnection.connection));
166
+ } catch (error) {
167
+ reject(error);
168
+ } finally {
169
+ availableConnection.busy = false;
170
+ // After query execution, process any queued tasks
171
+ this.processQueue();
172
+ }
173
+ } else {
174
+ // If no available connections, add to the queue
175
+ this.readQueue.push(execute);
176
+ }
177
+ };
178
+
179
+ execute();
163
180
  });
181
+ }
164
182
 
165
- return new Promise(async (resolve, reject) => {
166
- try {
167
- await this.locks.acquire(
168
- sortedConnections[0].lockKey,
169
- async () => {
170
- resolve(await fn(sortedConnections[0].connection));
171
- },
172
- { timeout: options?.timeoutMs }
173
- );
174
- } catch (ex) {
175
- reject(ex);
183
+ private async processQueue(): Promise<void> {
184
+ if (this.readQueue.length > 0) {
185
+ const next = this.readQueue.shift();
186
+ if (next) {
187
+ next();
176
188
  }
177
- });
189
+ }
178
190
  }
179
191
 
180
192
  async writeLock<T>(fn: (tx: OPSQLiteConnection) => Promise<T>, options?: DBLockOptions): Promise<T> {