Skip to content
Draft
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
18 changes: 18 additions & 0 deletions .changeset/funny-deers-explode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
'@powersync/react-native': major
'@powersync/web': major
'@powersync/capacitor': minor
'@powersync/common': minor
'@powersync/tauri-plugin': minor
'@powersync/node': minor
'@powersync/nuxt': minor
'@powersync/vue': minor
---

Rename `AbstractPowerSyncDatabase` to `CommonPowerSyncDatabase`, make it a TypeScript interface.

`CrudEntry` is now a TypeScript interface, remove it's constructor and `CrudEntry.fromRow`.

`SyncStatus` is no longer constructable in user code.

Remove `DataFlowStatus.downloading`. Use `SyncStatus.downloading` instead.
4 changes: 2 additions & 2 deletions demos/example-nextjs/src/components/StatusPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ function ArrowDown() {

export function StatusPanel() {
const status = useStatus();
const { connected, hasSynced, dataFlowStatus } = status;
const { uploading, downloading, uploadError, downloadError } = dataFlowStatus;
const { connected, hasSynced, downloading, dataFlowStatus } = status;
const { uploading, uploadError, downloadError } = dataFlowStatus;

let label = 'Connecting…';
let chipColor: keyof typeof chipStyles = 'warning';
Expand Down
4 changes: 2 additions & 2 deletions demos/react-multi-client/src/components/UserComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -200,13 +200,13 @@ export const UserComponent: React.FC<UserComponentProps> = (props) => {

const className = useMemo(() => {
return [
status.dataFlowStatus.downloading ? DOWNLOADING_CSS_CLASS : '',
status.downloading ? DOWNLOADING_CSS_CLASS : '',
status.dataFlowStatus.uploading ? UPLOADING_CSS_CLASS : '',
showOnline ? TOGGLE_ONLINE_CSS_CLASS : ''
]
.join(' ')
.trim();
}, [status.dataFlowStatus.downloading, status.dataFlowStatus.uploading, showOnline]);
}, [status.downloading, status.dataFlowStatus.uploading, showOnline]);

return (
<div className={className}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ export interface SystemProviderProps {
const SystemProvider: React.FC<PropsWithChildren<SystemProviderProps>> = (props) => {
const { client } = useSupabase();

const [connector] = React.useState(new SupabaseConnector(client));

const [powersync] = React.useState(
new TimedPowerSyncDatabase({
database: {
Expand All @@ -29,6 +27,8 @@ const SystemProvider: React.FC<PropsWithChildren<SystemProviderProps>> = (props)
})
);

const [connector] = React.useState(new SupabaseConnector(client, powersync));

React.useEffect(() => {
powersync.init();

Expand Down
46 changes: 23 additions & 23 deletions demos/react-multi-client/src/library/SupabaseConnector.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {
AbstractPowerSyncDatabase,
CommonPowerSyncDatabase,
BaseListener,
BaseObserver,
CrudEntry,
Mutex,
PowerSyncBackendConnector,
UpdateType
UpdateType,
Mutex
} from '@powersync/web';

import { Session, SupabaseClient } from '@supabase/supabase-js';
Expand All @@ -16,15 +16,17 @@ export interface SupabaseConnectorListener extends BaseListener {
}

export class SupabaseConnector extends BaseObserver<SupabaseConnectorListener> implements PowerSyncBackendConnector {
static SHARED_MUTEX = new Mutex();
static SHARED_MUTEX: Mutex | null = null;
readonly client: SupabaseClient;

ready: boolean;

currentSession: Session | null;

constructor(client: SupabaseClient) {
constructor(client: SupabaseClient, db: CommonPowerSyncDatabase) {
super();

SupabaseConnector.SHARED_MUTEX ??= db.createMutex();
this.client = client;
this.currentSession = null;
this.ready = false;
Expand All @@ -36,26 +38,24 @@ export class SupabaseConnector extends BaseObserver<SupabaseConnectorListener> i
}

// Ensures that we don't accidentally check/create multiple anon sessions during initialization
const release = await SupabaseConnector.SHARED_MUTEX.acquire();

let sessionResponse = await this.client.auth.getSession();
if (sessionResponse.error) {
console.error(sessionResponse.error);
throw sessionResponse.error;
} else if (!sessionResponse.data.session) {
const anonUser = await this.client.auth.signInAnonymously();
if (anonUser.error) {
throw anonUser.error;
await SupabaseConnector.SHARED_MUTEX!.runExclusive(async () => {
let sessionResponse = await this.client.auth.getSession();
if (sessionResponse.error) {
console.error(sessionResponse.error);
throw sessionResponse.error;
} else if (!sessionResponse.data.session) {
const anonUser = await this.client.auth.signInAnonymously();
if (anonUser.error) {
throw anonUser.error;
}
sessionResponse = await this.client.auth.getSession();
}
sessionResponse = await this.client.auth.getSession();
}

this.updateSession(sessionResponse.data.session);

this.ready = true;
this.iterateListeners((cb) => cb.initialized?.());
this.updateSession(sessionResponse.data.session);

release();
this.ready = true;
this.iterateListeners((cb) => cb.initialized?.());
});
}

async fetchCredentials() {
Expand All @@ -73,7 +73,7 @@ export class SupabaseConnector extends BaseObserver<SupabaseConnectorListener> i
};
}

async uploadData(database: AbstractPowerSyncDatabase): Promise<void> {
async uploadData(database: CommonPowerSyncDatabase): Promise<void> {
const transaction = await database.getNextCrudTransaction();
if (!transaction) {
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {
PowerSyncDatabase,
PowerSyncDBListener,
Transaction,
WebPowerSyncDatabaseOptions,
PowerSyncBackendConnector,
LockContext
LockContext,
WebPowerSyncDatabase
} from '@powersync/web';

export enum OperationType {
Expand All @@ -24,7 +24,7 @@ export interface TimedPowerSyncListener extends PowerSyncDBListener {
operationCompleted: (event: TimedOperation) => void;
}

export class TimedPowerSyncDatabase extends PowerSyncDatabase {
export class TimedPowerSyncDatabase extends WebPowerSyncDatabase {
localKey: string;

constructor(options: WebPowerSyncDatabaseOptions) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {
AbstractPowerSyncDatabase,
CommonPowerSyncDatabase,
BaseObserver,
CrudEntry,
PowerSyncBackendConnector,
Expand Down
3 changes: 2 additions & 1 deletion packages/adapter-sql-js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"test": "vitest"
},
"dependencies": {
"@powersync/common": "workspace:^"
"@powersync/common": "workspace:^",
"@powersync/shared-internals": "workspace:*"
},
"devDependencies": {
"@powersync/sql-js": "0.0.9",
Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-sql-js/rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ export default () => {
]
})
],
external: ['@powersync/common']
external: ['@powersync/common', '@powersync/shared-internals']
};
};
6 changes: 2 additions & 4 deletions packages/adapter-sql-js/src/SQLJSAdapter.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import {
BaseListener,
BaseObserver,
BaseListener,
BatchedUpdateNotification,
ConnectionPool,
ControlledExecutor,
createConsoleLogger,
DBAdapter,
DBAdapterDefaultMixin,
Expand All @@ -12,15 +11,14 @@ import {
DBLockOptions,
LockContext,
LogLevels,
Mutex,
PowerSyncLogger,
QueryResult,
SqlExecutor,
SQLOpenFactory,
SQLOpenOptions,
timeoutSignal,
Transaction
} from '@powersync/common';
import { Mutex, timeoutSignal, ControlledExecutor } from '@powersync/shared-internals';
// This uses a pure JS version which avoids the need for WebAssembly, which is not supported in React Native.
import SQLJs from '@powersync/sql-js/dist/sql-asm.js';

Expand Down
3 changes: 3 additions & 0 deletions packages/adapter-sql-js/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
"references": [
{
"path": "../common"
},
{
"path": "../shared-internals"
}
],
"include": ["src/**/*"]
Expand Down
2 changes: 1 addition & 1 deletion packages/attachments-storage-react-native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"@powersync/common": "workspace:*",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-node-resolve": "15.2.3",
"@rollup/plugin-typescript": "^11.1.6",
"@rollup/plugin-typescript": "^12.3.0",
"@dr.pogodin/react-native-fs": "^2.36.1",
"expo-file-system": "^19.0.21",
"rollup": "4.14.3",
Expand Down
2 changes: 1 addition & 1 deletion packages/attachments-storage-react-native/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"rootDir": "src",
"module": "node16",
"moduleResolution": "node16",
"target": "es6",
"target": "es2019",
"outDir": "./lib",
"strictNullChecks": true
},
Expand Down
3 changes: 3 additions & 0 deletions packages/capacitor/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@
"@capacitor-community/sqlite": "^8.1.0",
"@powersync/web": "workspace:^1.38.3"
},
"dependencies": {
"@powersync/shared-internals": "workspace:*"
},
"swiftlint": "@ionic/swiftlint-config",
"capacitor": {
"name": "PowerSyncCapacitor",
Expand Down
1 change: 1 addition & 0 deletions packages/capacitor/rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const external = [
'@capacitor/core',
'@capacitor-community/sqlite',
'@powersync/common',
'@powersync/shared-internals',
'@powersync/web',
'@journeyapps/wa-sqlite'
];
Expand Down
40 changes: 24 additions & 16 deletions packages/capacitor/src/PowerSyncDatabase.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,27 @@
import { Capacitor } from '@capacitor/core';
import {
CreateSyncImplementationOptions,
CommonPowerSyncDatabase,
DBAdapter,
LogLevels,
MEMORY_TRIGGER_CLAIM_MANAGER,
openDatabase,
PowerSyncBackendConnector,
StreamingSyncImplementation,
PowerSyncDatabaseConstructor,
SyncOptions,
SyncStreamConnectionMethod,
TriggerManagerConfig,
PowerSyncDatabase as WebPowerSyncDatabase,
WebSQLOpenOptions
WebPowerSyncDatabase,
WebPowerSyncDatabaseOptions
} from '@powersync/web';
import { CapacitorSQLiteAdapter } from './adapter/CapacitorSQLiteAdapter.js';
import { CapacitorRemote } from './sync/CapacitorRemote.js';
import { CapacitorStreamingSyncImplementation } from './sync/CapacitorSyncImplementation.js';
import {
CreateSyncImplementationOptions,
MEMORY_TRIGGER_CLAIM_MANAGER,
StreamingSyncImplementation,
TriggerManagerConfig,
openDatabase
} from '@powersync/shared-internals';

/**
* PowerSyncDatabase class for managing database connections and sync implementations.
* This extends the WebPowerSyncDatabase to provide platform-specific implementations
* for Capacitor environments (iOS and Android).
*
* @experimental
* @alpha
*/
export class PowerSyncDatabase extends WebPowerSyncDatabase {
class CapacitorPowerSyncDatabase extends WebPowerSyncDatabase {
/**
* Connects to stream of events from the PowerSync instance.
* {@link PowerSyncConnectionOptions#connectionMethod} defaults to WebSocket connection on Web platforms
Expand Down Expand Up @@ -137,3 +133,15 @@ export class PowerSyncDatabase extends WebPowerSyncDatabase {
}
}
}

/**
* PowerSyncDatabase class for managing database connections and sync implementations.
* This extends the WebPowerSyncDatabase to provide platform-specific implementations
* for Capacitor environments (iOS and Android).
*
* @experimental
* @alpha
*/
export const PowerSyncDatabase: PowerSyncDatabaseConstructor<WebPowerSyncDatabaseOptions> = CapacitorPowerSyncDatabase;

export interface PowerSyncDatabase extends CommonPowerSyncDatabase {}
5 changes: 2 additions & 3 deletions packages/capacitor/src/adapter/CapacitorSQLiteAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@ import {
DBAdapterListener,
DBLockOptions,
LockContext,
Mutex,
QueryResult,
timeoutSignal
QueryResult
} from '@powersync/web';
import { Mutex, timeoutSignal } from '@powersync/shared-internals';
import { PowerSyncCore } from '../plugin/PowerSyncCore.js';
import { messageForErrorCode } from '../plugin/PowerSyncPlugin.js';
import { CapacitorSQLiteOpenFactoryOptions, DEFAULT_SQLITE_OPTIONS } from './CapacitorSQLiteOpenFactory.js';
Expand Down
3 changes: 2 additions & 1 deletion packages/capacitor/src/sync/CapacitorSyncImplementation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AbstractStreamingSyncImplementation, LockOptions, LockType, Mutex } from '@powersync/web';
import { AbstractStreamingSyncImplementation, LockOptions, LockType } from '@powersync/shared-internals';
import { Mutex } from '@powersync/shared-internals';

type MutexMap = {
/**
Expand Down
2 changes: 1 addition & 1 deletion packages/capacitor/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@
},
"files": ["src/index.ts"],
"exclude": ["node_modules"],
"references": [{ "path": "../common" }, { "path": "../web" }]
"references": [{ "path": "../common" }, { "path": "../shared-internals" }, { "path": "../web" }]
}
Loading
Loading