Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/angry-foxes-hammer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@journeyapps/powersync-sdk-react-native': patch
---

Fixed watched queries from updating before writes have been commited on the write connection.
6 changes: 6 additions & 0 deletions .changeset/fast-chicken-vanish.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@journeyapps/powersync-sdk-react-native': minor
'@journeyapps/powersync-sdk-common': minor
---

Added the ability to receive batched table updates from DB adapters.
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "apps/supabase-todolist"]
path = apps/supabase-todolist
url = git@github.com:journeyapps/powersync-supabase-react-native-todolist-demo.git
url = git@github.com:powersync-ja/powersync-supabase-react-native-todolist-demo.git
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import _ from 'lodash';
import { Mutex } from 'async-mutex';
import Logger, { ILogger } from 'js-logger';
import { DBAdapter, QueryResult, Transaction } from '../db/DBAdapter';
import { DBAdapter, QueryResult, Transaction, isBatchedUpdateNotification } from '../db/DBAdapter';
import { Schema } from '../db/schema/Schema';
import { SyncStatus } from '../db/crud/SyncStatus';
import { UploadQueueStats } from '../db/crud/UploadQueueStatus';
Expand Down Expand Up @@ -511,15 +511,21 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB

const dispose = this.database.registerListener({
tablesUpdated: async (update) => {
const { table } = update;
const { rawTableNames } = options;

if (!rawTableNames && !table.match(POWERSYNC_TABLE_MATCH)) {
const tables = isBatchedUpdateNotification(update) ? update.tables : [update.table];

const filteredTables = rawTableNames ? tables : tables.filter((t) => !!t.match(POWERSYNC_TABLE_MATCH));
if (!filteredTables.length) {
return;
}

const tableName = rawTableNames ? table : table.replace(POWERSYNC_TABLE_MATCH, '');
throttledTableUpdates.push(tableName);
// Remove any PowerSync table prefixes if necessary
const mappedTableNames = rawTableNames
? filteredTables
: filteredTables.map((t) => t.replace(POWERSYNC_TABLE_MATCH, ''));

throttledTableUpdates.push(...mappedTableNames);

flushTableUpdates();
}
Expand Down
31 changes: 28 additions & 3 deletions packages/powersync-sdk-common/src/db/DBAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@

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

/**
* TODO most of these types could be exported to a common `types` package
* which is used by the DB adapter libraries as well.
*/

/**
* Object returned by SQL Query executions {
* insertId: Represent the auto-generated row id if applicable
Expand Down Expand Up @@ -54,14 +59,28 @@ export enum RowUpdateType {
SQLITE_DELETE = 9,
SQLITE_UPDATE = 23
}
export interface UpdateNotification {
export interface TableUpdateOperation {
opType: RowUpdateType;
table: string;
rowId: number;
}
export interface UpdateNotification extends TableUpdateOperation {
table: string;
}

export interface BatchedUpdateNotification {
rawUpdates: UpdateNotification[];
tables: string[];
groupedUpdates: Record<string, TableUpdateOperation[]>;
}

export interface DBAdapterListener extends BaseListener {
tablesUpdated: (updateNotification: UpdateNotification) => void;
/**
* Listener for table updates.
* Allows for single table updates in order to maintain API compatibility
* without the need for a major version bump
* The DB adapter can also batch update notifications if supported.
*/
tablesUpdated: (updateNotification: BatchedUpdateNotification | UpdateNotification) => void;
}

export interface DBLockOptions {
Expand All @@ -77,3 +96,9 @@ export interface DBAdapter extends BaseObserverInterface<DBAdapterListener>, DBG
writeLock: <T>(fn: (tx: LockContext) => Promise<T>, options?: DBLockOptions) => Promise<T>;
writeTransaction: <T>(fn: (tx: Transaction) => Promise<T>, options?: DBLockOptions) => Promise<T>;
}

export function isBatchedUpdateNotification(
update: BatchedUpdateNotification | UpdateNotification
): update is BatchedUpdateNotification {
return 'tables' in update;
}
4 changes: 2 additions & 2 deletions packages/powersync-sdk-react-native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
},
"homepage": "https://docs.powersync.co/",
"peerDependencies": {
"@journeyapps/react-native-quick-sqlite": "^1.0.0",
"@journeyapps/react-native-quick-sqlite": "^1.1.0",
"base-64": "^1.0.0",
"react": "*",
"react-native": "*",
Expand All @@ -44,7 +44,7 @@
"async-lock": "^1.4.0"
},
"devDependencies": {
"@journeyapps/react-native-quick-sqlite": "^1.0.0",
"@journeyapps/react-native-quick-sqlite": "^1.1.0",
"@types/async-lock": "^1.4.0",
"react-native": "0.72.4",
"react": "18.2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class RNQSDBAdapter extends BaseObserver<DBAdapterListener> implements DB
constructor(protected baseDB: QuickSQLiteConnection, public name: string) {
super();
// link table update commands
baseDB.registerUpdateHook((update) => {
baseDB.registerTablesChangedHook((update) => {
this.iterateListeners((cb) => cb.tablesUpdated?.(update));
});

Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2220,10 +2220,10 @@
"@types/yargs" "^17.0.8"
chalk "^4.0.0"

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