Skip to content

Commit 6983121

Browse files
[Fix] Watched query updates (#43)
* fix watched queries: watches now execute read queries after table changes have been commited
1 parent 8f26505 commit 6983121

File tree

8 files changed

+58
-16
lines changed

8 files changed

+58
-16
lines changed

.changeset/angry-foxes-hammer.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@journeyapps/powersync-sdk-react-native': patch
3+
---
4+
5+
Fixed watched queries from updating before writes have been commited on the write connection.

.changeset/fast-chicken-vanish.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@journeyapps/powersync-sdk-react-native': minor
3+
'@journeyapps/powersync-sdk-common': minor
4+
---
5+
6+
Added the ability to receive batched table updates from DB adapters.

.gitmodules

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
[submodule "apps/supabase-todolist"]
22
path = apps/supabase-todolist
3-
url = git@github.com:journeyapps/powersync-supabase-react-native-todolist-demo.git
3+
url = git@github.com:powersync-ja/powersync-supabase-react-native-todolist-demo.git

packages/powersync-sdk-common/src/client/AbstractPowerSyncDatabase.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import _ from 'lodash';
22
import { Mutex } from 'async-mutex';
33
import Logger, { ILogger } from 'js-logger';
4-
import { DBAdapter, QueryResult, Transaction } from '../db/DBAdapter';
4+
import { DBAdapter, QueryResult, Transaction, isBatchedUpdateNotification } from '../db/DBAdapter';
55
import { Schema } from '../db/schema/Schema';
66
import { SyncStatus } from '../db/crud/SyncStatus';
77
import { UploadQueueStats } from '../db/crud/UploadQueueStatus';
@@ -511,15 +511,21 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
511511

512512
const dispose = this.database.registerListener({
513513
tablesUpdated: async (update) => {
514-
const { table } = update;
515514
const { rawTableNames } = options;
516515

517-
if (!rawTableNames && !table.match(POWERSYNC_TABLE_MATCH)) {
516+
const tables = isBatchedUpdateNotification(update) ? update.tables : [update.table];
517+
518+
const filteredTables = rawTableNames ? tables : tables.filter((t) => !!t.match(POWERSYNC_TABLE_MATCH));
519+
if (!filteredTables.length) {
518520
return;
519521
}
520522

521-
const tableName = rawTableNames ? table : table.replace(POWERSYNC_TABLE_MATCH, '');
522-
throttledTableUpdates.push(tableName);
523+
// Remove any PowerSync table prefixes if necessary
524+
const mappedTableNames = rawTableNames
525+
? filteredTables
526+
: filteredTables.map((t) => t.replace(POWERSYNC_TABLE_MATCH, ''));
527+
528+
throttledTableUpdates.push(...mappedTableNames);
523529

524530
flushTableUpdates();
525531
}

packages/powersync-sdk-common/src/db/DBAdapter.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55

66
import { BaseListener, BaseObserverInterface } from '../utils/BaseObserver';
77

8+
/**
9+
* TODO most of these types could be exported to a common `types` package
10+
* which is used by the DB adapter libraries as well.
11+
*/
12+
813
/**
914
* Object returned by SQL Query executions {
1015
* insertId: Represent the auto-generated row id if applicable
@@ -54,14 +59,28 @@ export enum RowUpdateType {
5459
SQLITE_DELETE = 9,
5560
SQLITE_UPDATE = 23
5661
}
57-
export interface UpdateNotification {
62+
export interface TableUpdateOperation {
5863
opType: RowUpdateType;
59-
table: string;
6064
rowId: number;
6165
}
66+
export interface UpdateNotification extends TableUpdateOperation {
67+
table: string;
68+
}
69+
70+
export interface BatchedUpdateNotification {
71+
rawUpdates: UpdateNotification[];
72+
tables: string[];
73+
groupedUpdates: Record<string, TableUpdateOperation[]>;
74+
}
6275

6376
export interface DBAdapterListener extends BaseListener {
64-
tablesUpdated: (updateNotification: UpdateNotification) => void;
77+
/**
78+
* Listener for table updates.
79+
* Allows for single table updates in order to maintain API compatibility
80+
* without the need for a major version bump
81+
* The DB adapter can also batch update notifications if supported.
82+
*/
83+
tablesUpdated: (updateNotification: BatchedUpdateNotification | UpdateNotification) => void;
6584
}
6685

6786
export interface DBLockOptions {
@@ -77,3 +96,9 @@ export interface DBAdapter extends BaseObserverInterface<DBAdapterListener>, DBG
7796
writeLock: <T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions) => Promise<T>;
7897
writeTransaction: <T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions) => Promise<T>;
7998
}
99+
100+
export function isBatchedUpdateNotification(
101+
update: BatchedUpdateNotification | UpdateNotification
102+
): update is BatchedUpdateNotification {
103+
return 'tables' in update;
104+
}

packages/powersync-sdk-react-native/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
},
2828
"homepage": "https://docs.powersync.co/",
2929
"peerDependencies": {
30-
"@journeyapps/react-native-quick-sqlite": "^1.0.0",
30+
"@journeyapps/react-native-quick-sqlite": "^1.1.0",
3131
"base-64": "^1.0.0",
3232
"react": "*",
3333
"react-native": "*",
@@ -44,7 +44,7 @@
4444
"async-lock": "^1.4.0"
4545
},
4646
"devDependencies": {
47-
"@journeyapps/react-native-quick-sqlite": "^1.0.0",
47+
"@journeyapps/react-native-quick-sqlite": "^1.1.0",
4848
"@types/async-lock": "^1.4.0",
4949
"react-native": "0.72.4",
5050
"react": "18.2.0",

packages/powersync-sdk-react-native/src/db/adapters/react-native-quick-sqlite/RNQSDBAdapter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export class RNQSDBAdapter extends BaseObserver<DBAdapterListener> implements DB
2121
constructor(protected baseDB: QuickSQLiteConnection, public name: string) {
2222
super();
2323
// link table update commands
24-
baseDB.registerUpdateHook((update) => {
24+
baseDB.registerTablesChangedHook((update) => {
2525
this.iterateListeners((cb) => cb.tablesUpdated?.(update));
2626
});
2727

yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2220,10 +2220,10 @@
22202220
"@types/yargs" "^17.0.8"
22212221
chalk "^4.0.0"
22222222

2223-
"@journeyapps/react-native-quick-sqlite@^1.0.0":
2224-
version "1.0.0"
2225-
resolved "https://registry.npmjs.org/@journeyapps/react-native-quick-sqlite/-/react-native-quick-sqlite-1.0.0.tgz#bb836a82a64705a2be6de27560b1e8816bba19d0"
2226-
integrity sha512-rQPE5OoMfXCyBBnCNMhkd4pES8zt0CbxiWb6GfZ04ik/cKji14GWBkvw9YZdyutc3zb3CNiexHYP1xZzlQYTQg==
2223+
"@journeyapps/react-native-quick-sqlite@^1.0.0", "@journeyapps/react-native-quick-sqlite@^1.1.0":
2224+
version "1.1.0"
2225+
resolved "https://registry.npmjs.org/@journeyapps/react-native-quick-sqlite/-/react-native-quick-sqlite-1.1.0.tgz#cf4aa6694b7232d0f86e565fdba4e41ef15d80cc"
2226+
integrity sha512-Pg6VA6ABC7N5FrNB5eqTgNsKdzzmDSp5aBtnQh1BlcZu7ISPZdCcKo+ZJtKyzTAWpc17LIttvJwxez6zBxUdOw==
22272227
dependencies:
22282228
lodash "^4.17.21"
22292229
uuid "3.4.0"

0 commit comments

Comments
 (0)