Skip to content

Commit 5edc181

Browse files
committed
Merge branch 'main' into chore/rnw-expo-52-housekeeping
2 parents 7113bb8 + fc90fba commit 5edc181

File tree

28 files changed

+595
-131
lines changed

28 files changed

+595
-131
lines changed

.changeset/sour-spiders-rhyme.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

packages/attachments/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
"test": "pnpm build && vitest"
3030
},
3131
"peerDependencies": {
32-
"@powersync/common": "workspace:^1.26.0"
32+
"@powersync/common": "workspace:^1.27.1"
3333
},
3434
"devDependencies": {
3535
"@powersync/common": "workspace:*",

packages/common/CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# @powersync/common
22

3+
## 1.27.1
4+
5+
### Patch Changes
6+
7+
- 720ad7a: Fix a race condition causing sync changes during uploads not to be applied.
8+
9+
## 1.27.0
10+
11+
### Minor Changes
12+
13+
- b722378: Added `downloadError` and `uploadError` members to `SyncDataFlowStatus` of `SyncStatus`.
14+
315
## 1.26.0
416

517
### Minor Changes

packages/common/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@powersync/common",
3-
"version": "1.26.0",
3+
"version": "1.27.1",
44
"publishConfig": {
55
"registry": "https://registry.npmjs.org/",
66
"access": "public"

packages/common/src/client/AbstractPowerSyncDatabase.ts

Lines changed: 78 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { Schema } from '../db/schema/Schema.js';
1515
import { BaseObserver } from '../utils/BaseObserver.js';
1616
import { ControlledExecutor } from '../utils/ControlledExecutor.js';
1717
import { mutexRunExclusive } from '../utils/mutex.js';
18-
import { throttleTrailing } from '../utils/throttle.js';
18+
import { throttleTrailing } from '../utils/async.js';
1919
import { SQLOpenFactory, SQLOpenOptions, isDBAdapter, isSQLOpenFactory, isSQLOpenOptions } from './SQLOpenFactory.js';
2020
import { PowerSyncBackendConnector } from './connection/PowerSyncBackendConnector.js';
2121
import { runOnSchemaChange } from './runOnSchemaChange.js';
@@ -267,7 +267,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
267267
/**
268268
* Wait for the first sync operation to complete.
269269
*
270-
* @argument request Either an abort signal (after which the promise will complete regardless of
270+
* @param request Either an abort signal (after which the promise will complete regardless of
271271
* whether a full sync was completed) or an object providing an abort signal and a priority target.
272272
* When a priority target is set, the promise may complete when all buckets with the given (or higher)
273273
* priorities have been synchronized. This can be earlier than a complete sync.
@@ -540,7 +540,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
540540
}
541541

542542
/**
543-
* Get a batch of crud data to upload.
543+
* Get a batch of CRUD data to upload.
544544
*
545545
* Returns null if there is no data to upload.
546546
*
@@ -555,6 +555,9 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
555555
* This method does include transaction ids in the result, but does not group
556556
* data by transaction. One batch may contain data from multiple transactions,
557557
* and a single transaction may be split over multiple batches.
558+
*
559+
* @param limit Maximum number of CRUD entries to include in the batch
560+
* @returns A batch of CRUD operations to upload, or null if there are none
558561
*/
559562
async getCrudBatch(limit: number = DEFAULT_CRUD_BATCH_LIMIT): Promise<CrudBatch | null> {
560563
const result = await this.getAll<CrudEntryJSON>(
@@ -591,6 +594,8 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
591594
*
592595
* Unlike {@link getCrudBatch}, this only returns data from a single transaction at a time.
593596
* All data for the transaction is loaded into memory.
597+
*
598+
* @returns A transaction of CRUD operations to upload, or null if there are none
594599
*/
595600
async getNextCrudTransaction(): Promise<CrudTransaction | null> {
596601
return await this.readTransaction(async (tx) => {
@@ -628,6 +633,8 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
628633
* Get an unique client id for this database.
629634
*
630635
* The id is not reset when the database is cleared, only when the database is deleted.
636+
*
637+
* @returns A unique identifier for the database instance
631638
*/
632639
async getClientId(): Promise<string> {
633640
return this.bucketStorageAdapter.getClientId();
@@ -652,14 +659,27 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
652659
}
653660

654661
/**
655-
* Execute a write (INSERT/UPDATE/DELETE) query
662+
* Execute a SQL write (INSERT/UPDATE/DELETE) query
656663
* and optionally return results.
664+
*
665+
* @param sql The SQL query to execute
666+
* @param parameters Optional array of parameters to bind to the query
667+
* @returns The query result as an object with structured key-value pairs
657668
*/
658669
async execute(sql: string, parameters?: any[]) {
659670
await this.waitForReady();
660671
return this.database.execute(sql, parameters);
661672
}
662673

674+
/**
675+
* Execute a SQL write (INSERT/UPDATE/DELETE) query directly on the database without any PowerSync processing.
676+
* This bypasses certain PowerSync abstractions and is useful for accessing the raw database results.
677+
*
678+
* @param sql The SQL query to execute
679+
* @param parameters Optional array of parameters to bind to the query
680+
* @returns The raw query result from the underlying database as a nested array of raw values, where each row is
681+
* represented as an array of column values without field names.
682+
*/
663683
async executeRaw(sql: string, parameters?: any[]) {
664684
await this.waitForReady();
665685
return this.database.executeRaw(sql, parameters);
@@ -669,6 +689,10 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
669689
* Execute a write query (INSERT/UPDATE/DELETE) multiple times with each parameter set
670690
* and optionally return results.
671691
* This is faster than executing separately with each parameter set.
692+
*
693+
* @param sql The SQL query to execute
694+
* @param parameters Optional 2D array of parameter sets, where each inner array is a set of parameters for one execution
695+
* @returns The query result
672696
*/
673697
async executeBatch(sql: string, parameters?: any[][]) {
674698
await this.waitForReady();
@@ -677,6 +701,10 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
677701

678702
/**
679703
* Execute a read-only query and return results.
704+
*
705+
* @param sql The SQL query to execute
706+
* @param parameters Optional array of parameters to bind to the query
707+
* @returns An array of results
680708
*/
681709
async getAll<T>(sql: string, parameters?: any[]): Promise<T[]> {
682710
await this.waitForReady();
@@ -685,6 +713,10 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
685713

686714
/**
687715
* Execute a read-only query and return the first result, or null if the ResultSet is empty.
716+
*
717+
* @param sql The SQL query to execute
718+
* @param parameters Optional array of parameters to bind to the query
719+
* @returns The first result if found, or null if no results are returned
688720
*/
689721
async getOptional<T>(sql: string, parameters?: any[]): Promise<T | null> {
690722
await this.waitForReady();
@@ -693,6 +725,11 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
693725

694726
/**
695727
* Execute a read-only query and return the first result, error if the ResultSet is empty.
728+
*
729+
* @param sql The SQL query to execute
730+
* @param parameters Optional array of parameters to bind to the query
731+
* @returns The first result matching the query
732+
* @throws Error if no rows are returned
696733
*/
697734
async get<T>(sql: string, parameters?: any[]): Promise<T> {
698735
await this.waitForReady();
@@ -724,6 +761,11 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
724761
* Open a read-only transaction.
725762
* Read transactions can run concurrently to a write transaction.
726763
* Changes from any write transaction are not visible to read transactions started before it.
764+
*
765+
* @param callback Function to execute within the transaction
766+
* @param lockTimeout Time in milliseconds to wait for a lock before throwing an error
767+
* @returns The result of the callback
768+
* @throws Error if the lock cannot be obtained within the timeout period
727769
*/
728770
async readTransaction<T>(
729771
callback: (tx: Transaction) => Promise<T>,
@@ -744,6 +786,11 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
744786
* Open a read-write transaction.
745787
* This takes a global lock - only one write transaction can execute against the database at a time.
746788
* Statements within the transaction must be done on the provided {@link Transaction} interface.
789+
*
790+
* @param callback Function to execute within the transaction
791+
* @param lockTimeout Time in milliseconds to wait for a lock before throwing an error
792+
* @returns The result of the callback
793+
* @throws Error if the lock cannot be obtained within the timeout period
747794
*/
748795
async writeTransaction<T>(
749796
callback: (tx: Transaction) => Promise<T>,
@@ -818,6 +865,11 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
818865
* Source tables are automatically detected using `EXPLAIN QUERY PLAN`.
819866
*
820867
* Note that the `onChange` callback member of the handler is required.
868+
*
869+
* @param sql The SQL query to execute
870+
* @param parameters Optional array of parameters to bind to the query
871+
* @param handler Callbacks for handling results and errors
872+
* @param options Options for configuring watch behavior
821873
*/
822874
watchWithCallback(sql: string, parameters?: any[], handler?: WatchHandler, options?: SQLWatchOptions): void {
823875
const { onResult, onError = (e: Error) => this.options.logger?.error(e) } = handler ?? {};
@@ -863,6 +915,11 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
863915
* Execute a read query every time the source tables are modified.
864916
* Use {@link SQLWatchOptions.throttleMs} to specify the minimum interval between queries.
865917
* Source tables are automatically detected using `EXPLAIN QUERY PLAN`.
918+
*
919+
* @param sql The SQL query to execute
920+
* @param parameters Optional array of parameters to bind to the query
921+
* @param options Options for configuring watch behavior
922+
* @returns An AsyncIterable that yields QueryResults whenever the data changes
866923
*/
867924
watchWithAsyncGenerator(sql: string, parameters?: any[], options?: SQLWatchOptions): AsyncIterable<QueryResult> {
868925
return new EventIterator<QueryResult>((eventOptions) => {
@@ -883,6 +940,16 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
883940
});
884941
}
885942

943+
/**
944+
* Resolves the list of tables that are used in a SQL query.
945+
* If tables are specified in the options, those are used directly.
946+
* Otherwise, analyzes the query using EXPLAIN to determine which tables are accessed.
947+
*
948+
* @param sql The SQL query to analyze
949+
* @param parameters Optional parameters for the SQL query
950+
* @param options Optional watch options that may contain explicit table list
951+
* @returns Array of table names that the query depends on
952+
*/
886953
async resolveTables(sql: string, parameters?: any[], options?: SQLWatchOptions): Promise<string[]> {
887954
const resolvedTables = options?.tables ? [...options.tables] : [];
888955
if (!options?.tables) {
@@ -955,7 +1022,9 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
9551022
*
9561023
* Note that the `onChange` callback member of the handler is required.
9571024
*
958-
* Returns dispose function to stop watching.
1025+
* @param handler Callbacks for handling change events and errors
1026+
* @param options Options for configuring watch behavior
1027+
* @returns A dispose function to stop watching for changes
9591028
*/
9601029
onChangeWithCallback(handler?: WatchOnChangeHandler, options?: SQLWatchOptions): () => void {
9611030
const { onChange, onError = (e: Error) => this.options.logger?.error(e) } = handler ?? {};
@@ -1008,8 +1077,11 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
10081077
*
10091078
* This is preferred over {@link watchWithAsyncGenerator} when multiple queries need to be performed
10101079
* together when data is changed.
1080+
*
1081+
* Note: do not declare this as `async *onChange` as it will not work in React Native.
10111082
*
1012-
* Note, do not declare this as `async *onChange` as it will not work in React Native
1083+
* @param options Options for configuring watch behavior
1084+
* @returns An AsyncIterable that yields change events whenever the specified tables change
10131085
*/
10141086
onChangeWithAsyncGenerator(options?: SQLWatchOptions): AsyncIterable<WatchOnChangeEvent> {
10151087
const resolvedOptions = options ?? {};

0 commit comments

Comments
 (0)