diff --git a/packages/powersync-react/src/hooks/usePowerSyncQuery.ts b/packages/powersync-react/src/hooks/usePowerSyncQuery.ts index 0fed38d0..955736dd 100644 --- a/packages/powersync-react/src/hooks/usePowerSyncQuery.ts +++ b/packages/powersync-react/src/hooks/usePowerSyncQuery.ts @@ -3,7 +3,7 @@ import { usePowerSync } from './PowerSyncContext'; /** * A hook to access a single static query. - * For an updated result, use usePowerSyncWatchedQuery instead + * For an updated result, use {@link usePowerSyncWatchedQuery} instead */ export const usePowerSyncQuery = (sqlStatement: string, parameters: any[] = []): T[] => { const powerSync = usePowerSync(); diff --git a/packages/powersync-sdk-common/src/client/AbstractPowerSyncDatabase.ts b/packages/powersync-sdk-common/src/client/AbstractPowerSyncDatabase.ts index bad6431b..497c489f 100644 --- a/packages/powersync-sdk-common/src/client/AbstractPowerSyncDatabase.ts +++ b/packages/powersync-sdk-common/src/client/AbstractPowerSyncDatabase.ts @@ -21,10 +21,12 @@ import { EventIterator } from 'event-iterator'; import { quoteIdentifier } from '../utils/strings'; export interface DisconnectAndClearOptions { + /** When set to false, data in local-only tables is preserved. */ clearLocal?: boolean; } export interface PowerSyncDatabaseOptions { + /** Schema used for the local database. */ schema: Schema; database: DBAdapter; /** @@ -44,6 +46,7 @@ export interface PowerSyncDatabaseOptions { export interface SQLWatchOptions { signal?: AbortSignal; tables?: string[]; + /** The minimum interval between queries. */ throttleMs?: number; /** * Allows for watching any SQL table @@ -114,14 +117,25 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver cb.initialized?.()); } + /** + * Replace the schema with a new version. This is for advanced use cases - typically the schema should just be specified once in the constructor. + * + * Cannot be used while connected - this should only be called before {@link AbstractPowerSyncDatabase.connect}. + */ async updateSchema(schema: Schema) { if (this.abortController) { throw new Error('Cannot update schema while connected'); @@ -226,6 +245,11 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver { @@ -413,7 +439,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver(sql: string, parameters?: any[]): Promise { await this.waitForReady(); @@ -446,8 +472,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver(callback: (db: DBAdapter) => Promise) { await this.waitForReady(); @@ -456,7 +481,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver(callback: (db: DBAdapter) => Promise) { await this.waitForReady(); @@ -466,6 +491,11 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver( callback: (tx: Transaction) => Promise, lockTimeout: number = DEFAULT_LOCK_TIMEOUT_MS @@ -481,6 +511,11 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver( callback: (tx: Transaction) => Promise, lockTimeout: number = DEFAULT_LOCK_TIMEOUT_MS @@ -496,6 +531,11 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver { //Fetch initial data yield await this.executeReadOnly(sql, parameters); @@ -524,7 +564,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver { + /** Schema used for the local database. */ schema: Schema; /** * Filename for the database. @@ -20,6 +21,9 @@ export abstract class AbstractPowerSyncDatabaseOpenFactory { options.logger = options.logger ?? Logger.get(`PowerSync ${this.options.dbFilename}`); } + /** + * Schema used for the local database. + */ get schema() { return this.options.schema; } diff --git a/packages/powersync-sdk-common/src/client/connection/PowerSyncBackendConnector.ts b/packages/powersync-sdk-common/src/client/connection/PowerSyncBackendConnector.ts index 10c9ae11..131f3024 100644 --- a/packages/powersync-sdk-common/src/client/connection/PowerSyncBackendConnector.ts +++ b/packages/powersync-sdk-common/src/client/connection/PowerSyncBackendConnector.ts @@ -16,7 +16,7 @@ export interface PowerSyncBackendConnector { /** Upload local changes to the app backend. * - * Use [PowerSyncDatabase.getCrudBatch] to get a batch of changes to upload. See [DevConnector] for an example implementation. + * Use {@link AbstractPowerSyncDatabase.getCrudBatch} to get a batch of changes to upload. * * Any thrown errors will result in a retry after the configured wait period (default: 5 seconds). */ diff --git a/packages/powersync-sdk-common/src/client/sync/bucket/CrudBatch.ts b/packages/powersync-sdk-common/src/client/sync/bucket/CrudBatch.ts index 51ac45fc..6891f24e 100644 --- a/packages/powersync-sdk-common/src/client/sync/bucket/CrudBatch.ts +++ b/packages/powersync-sdk-common/src/client/sync/bucket/CrudBatch.ts @@ -1,9 +1,21 @@ import { CrudEntry } from './CrudEntry'; +/** + * A batch of client-side changes. + */ export class CrudBatch { constructor( + /** + * List of client-side changes. + */ public crud: CrudEntry[], + /** + * true if there are more changes in the local queue. + */ public haveMore: boolean, + /** + * Call to remove the changes from the local queue, once successfully uploaded. + */ public complete: (writeCheckpoint?: string) => Promise ) {} } diff --git a/packages/powersync-sdk-common/src/client/sync/bucket/CrudEntry.ts b/packages/powersync-sdk-common/src/client/sync/bucket/CrudEntry.ts index 25732ae7..481104c9 100644 --- a/packages/powersync-sdk-common/src/client/sync/bucket/CrudEntry.ts +++ b/packages/powersync-sdk-common/src/client/sync/bucket/CrudEntry.ts @@ -38,12 +38,33 @@ export type CrudEntryOutputJSON = { data: Record; }; +/** + * A single client-side change. + */ export class CrudEntry { + /** + * Auto-incrementing client-side id. + */ clientId: number; + /** + * ID of the changed row. + */ id: string; + /** + * Type of change. + */ op: UpdateType; + /** + * Data associated with the change. + */ opData?: Record; + /** + * Table that contained the change. + */ table: string; + /** + * Auto-incrementing transaction id. This is the same for all operations within the same transaction. + */ transactionId?: number; static fromRow(dbRow: CrudEntryJSON) { @@ -67,6 +88,9 @@ export class CrudEntry { this.transactionId = transactionId; } + /** + * Converts the change to JSON format. + */ toJSON(): CrudEntryOutputJSON { return { op_id: this.clientId, @@ -78,6 +102,9 @@ export class CrudEntry { }; } + /** + * The hash code for this object. + */ hashCode() { return hash([this.transactionId, this.clientId, this.op, this.table, this.id, this.opData]); } diff --git a/packages/powersync-sdk-common/src/client/sync/bucket/CrudTransaction.ts b/packages/powersync-sdk-common/src/client/sync/bucket/CrudTransaction.ts index 1a726b23..8b2955f8 100644 --- a/packages/powersync-sdk-common/src/client/sync/bucket/CrudTransaction.ts +++ b/packages/powersync-sdk-common/src/client/sync/bucket/CrudTransaction.ts @@ -3,8 +3,17 @@ import { CrudEntry } from './CrudEntry'; export class CrudTransaction extends CrudBatch { constructor( + /** + * List of client-side changes. + */ public crud: CrudEntry[], + /** + * Call to remove the changes from the local queue, once successfully uploaded. + */ public complete: (checkpoint?: string) => Promise, + /** + * If null, this contains a list of changes recorded without an explicit transaction associated. + */ public transactionId?: number ) { super(crud, false, complete); diff --git a/packages/powersync-sdk-common/src/client/sync/bucket/SqliteBucketStorage.ts b/packages/powersync-sdk-common/src/client/sync/bucket/SqliteBucketStorage.ts index 6a0310d2..0c727ee9 100644 --- a/packages/powersync-sdk-common/src/client/sync/bucket/SqliteBucketStorage.ts +++ b/packages/powersync-sdk-common/src/client/sync/bucket/SqliteBucketStorage.ts @@ -80,8 +80,6 @@ export class SqliteBucketStorage implements BucketStorageAdapter { /** * Mark a bucket for deletion. - * - * @param bucket */ private async deleteBucket(bucket: string) { // Delete a bucket, but allow it to be re-created. diff --git a/packages/powersync-sdk-common/src/db/DBAdapter.ts b/packages/powersync-sdk-common/src/db/DBAdapter.ts index 26aba198..159c2aed 100644 --- a/packages/powersync-sdk-common/src/db/DBAdapter.ts +++ b/packages/powersync-sdk-common/src/db/DBAdapter.ts @@ -11,18 +11,14 @@ import { BaseListener, BaseObserverInterface } from '../utils/BaseObserver'; */ /** - * Object returned by SQL Query executions { - * insertId: Represent the auto-generated row id if applicable - * rowsAffected: Number of affected rows if result of a update query - * message: if status === 1, here you will find error description - * rows: if status is undefined or 0 this object will contain the query results - * } - * - * @interface QueryResult + * Object returned by SQL Query executions. */ export type QueryResult = { + /** Represents the auto-generated row id if applicable. */ insertId?: number; + /** Number of affected rows if result of a update query. */ rowsAffected: number; + /** if status is undefined or 0 this object will contain the query results */ rows?: { /** Raw array with all dataset */ _array: any[]; @@ -37,12 +33,16 @@ export type QueryResult = { }; export interface DBGetUtils { + /** Execute a read-only query and return results. */ getAll(sql: string, parameters?: any[]): Promise; + /** Execute a read-only query and return the first result, or null if the ResultSet is empty. */ getOptional(sql: string, parameters?: any[]): Promise; + /** Execute a read-only query and return the first result, error if the ResultSet is empty. */ get(sql: string, parameters?: any[]): Promise; } export interface LockContext extends DBGetUtils { + /** Execute a statement and optionally return results. */ execute: (query: string, params?: any[] | undefined) => Promise; } @@ -63,6 +63,10 @@ export interface TableUpdateOperation { opType: RowUpdateType; rowId: number; } + +/** + * Notification of an update to one or more tables, for the purpose of realtime change notifications. + */ export interface UpdateNotification extends TableUpdateOperation { table: string; } diff --git a/packages/powersync-sdk-common/src/db/crud/SyncStatus.ts b/packages/powersync-sdk-common/src/db/crud/SyncStatus.ts index e4d5e14f..49047503 100644 --- a/packages/powersync-sdk-common/src/db/crud/SyncStatus.ts +++ b/packages/powersync-sdk-common/src/db/crud/SyncStatus.ts @@ -14,18 +14,35 @@ export type SyncStatusOptions = { export class SyncStatus { constructor(protected options: SyncStatusOptions) {} + /** + * true if currently connected. + */ get connected() { return this.options.connected ?? false; } + /** + * Time that a last sync has fully completed, if any. + * Currently this is reset to null after a restart. + */ get lastSyncedAt() { return this.options.lastSyncedAt; } + /** + * Upload/download status + */ get dataFlowStatus() { return ( this.options.dataFlow ?? { + /** + * true if actively downloading changes. + * This is only true when {@link connected} is also true. + */ downloading: false, + /** + * true if uploading changes. + */ uploading: false } ); diff --git a/packages/powersync-sdk-common/src/db/crud/UploadQueueStatus.ts b/packages/powersync-sdk-common/src/db/crud/UploadQueueStatus.ts index 8ad7e5d2..53fcde73 100644 --- a/packages/powersync-sdk-common/src/db/crud/UploadQueueStatus.ts +++ b/packages/powersync-sdk-common/src/db/crud/UploadQueueStatus.ts @@ -1,6 +1,12 @@ export class UploadQueueStats { constructor( + /** + * Number of records in the upload queue. + */ public count: number, + /** + * Size of the upload queue in bytes. + */ public size: number = null ) {}