@@ -9,14 +9,13 @@ import {
99 UpdateNotification ,
1010 isBatchedUpdateNotification
1111} from '../db/DBAdapter.js' ;
12- import { FULL_SYNC_PRIORITY } from '../db/crud/SyncProgress.js' ;
13- import { SyncPriorityStatus , SyncStatus } from '../db/crud/SyncStatus.js' ;
12+ import { SyncStatus } from '../db/crud/SyncStatus.js' ;
1413import { UploadQueueStats } from '../db/crud/UploadQueueStatus.js' ;
1514import { Schema } from '../db/schema/Schema.js' ;
1615import { BaseObserver } from '../utils/BaseObserver.js' ;
1716import { ControlledExecutor } from '../utils/ControlledExecutor.js' ;
1817import { symbolAsyncIterator , throttleTrailing } from '../utils/async.js' ;
19- import { ConnectionManager } from './ConnectionManager.js' ;
18+ import { ConnectionManager , CreateSyncImplementationOptions } from './ConnectionManager.js' ;
2019import { CustomQuery } from './CustomQuery.js' ;
2120import { ArrayQueryDefinition , Query } from './Query.js' ;
2221import { SQLOpenFactory , SQLOpenOptions , isDBAdapter , isSQLOpenFactory , isSQLOpenOptions } from './SQLOpenFactory.js' ;
@@ -40,6 +39,7 @@ import { TriggerManagerImpl } from './triggers/TriggerManagerImpl.js';
4039import { DEFAULT_WATCH_THROTTLE_MS , WatchCompatibleQuery } from './watched/WatchedQuery.js' ;
4140import { OnChangeQueryProcessor } from './watched/processors/OnChangeQueryProcessor.js' ;
4241import { WatchedQueryComparator } from './watched/processors/comparators.js' ;
42+ import { coreStatusToJs , CoreSyncStatus } from './sync/stream/core-instruction.js' ;
4343
4444export interface DisconnectAndClearOptions {
4545 /** When set to false, data in local-only tables is preserved. */
@@ -237,9 +237,15 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
237237
238238 // Start async init
239239 this . connectionManager = new ConnectionManager ( {
240+ firstStatusMatching : ( predicate ) => this . waitForStatus ( predicate ) ,
241+ resolveOfflineSyncStatus : ( ) => this . resolveOfflineSyncStatus ( ) ,
242+ rustSubscriptionsCommand : async ( payload ) => {
243+ await this . writeTransaction ( ( tx ) => {
244+ return tx . execute ( 'select powersync_control(?,?)' , [ 'subscriptions' , JSON . stringify ( payload ) ] ) ;
245+ } ) ;
246+ } ,
240247 createSyncImplementation : async ( connector , options ) => {
241248 await this . waitForReady ( ) ;
242-
243249 return this . runExclusive ( async ( ) => {
244250 const sync = this . generateSyncStreamImplementation ( connector , this . resolvedConnectionOptions ( options ) ) ;
245251 const onDispose = sync . registerListener ( {
@@ -304,7 +310,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
304310
305311 protected abstract generateSyncStreamImplementation (
306312 connector : PowerSyncBackendConnector ,
307- options : RequiredAdditionalConnectionOptions
313+ options : CreateSyncImplementationOptions & RequiredAdditionalConnectionOptions
308314 ) : StreamingSyncImplementation ;
309315
310316 protected abstract generateBucketStorageAdapter ( ) : BucketStorageAdapter ;
@@ -338,13 +344,18 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
338344 ? ( status : SyncStatus ) => status . hasSynced
339345 : ( status : SyncStatus ) => status . statusForPriority ( priority ) . hasSynced ;
340346
341- if ( statusMatches ( this . currentStatus ) ) {
347+ return this . waitForStatus ( statusMatches , signal ) ;
348+ }
349+
350+ private async waitForStatus ( predicate : ( status : SyncStatus ) => any , signal ?: AbortSignal ) : Promise < void > {
351+ if ( predicate ( this . currentStatus ) ) {
342352 return ;
343353 }
354+
344355 return new Promise ( ( resolve ) => {
345356 const dispose = this . registerListener ( {
346357 statusChanged : ( status ) => {
347- if ( statusMatches ( status ) ) {
358+ if ( predicate ( status ) ) {
348359 dispose ( ) ;
349360 resolve ( ) ;
350361 }
@@ -373,7 +384,7 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
373384 await this . bucketStorageAdapter . init ( ) ;
374385 await this . _loadVersion ( ) ;
375386 await this . updateSchema ( this . options . schema ) ;
376- await this . updateHasSynced ( ) ;
387+ await this . resolveOfflineSyncStatus ( ) ;
377388 await this . database . execute ( 'PRAGMA RECURSIVE_TRIGGERS=TRUE' ) ;
378389 this . ready = true ;
379390 this . iterateListeners ( ( cb ) => cb . initialized ?.( ) ) ;
@@ -403,30 +414,13 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
403414 }
404415 }
405416
406- protected async updateHasSynced ( ) {
407- const result = await this . database . getAll < { priority : number ; last_synced_at : string } > (
408- 'SELECT priority, last_synced_at FROM ps_sync_state ORDER BY priority DESC'
409- ) ;
410- let lastCompleteSync : Date | undefined ;
411- const priorityStatusEntries : SyncPriorityStatus [ ] = [ ] ;
417+ protected async resolveOfflineSyncStatus ( ) {
418+ const result = await this . database . get < { r : string } > ( 'SELECT powersync_offline_sync_status() as r' ) ;
419+ const parsed = JSON . parse ( result . r ) as CoreSyncStatus ;
412420
413- for ( const { priority, last_synced_at } of result ) {
414- const parsedDate = new Date ( last_synced_at + 'Z' ) ;
415-
416- if ( priority == FULL_SYNC_PRIORITY ) {
417- // This lowest-possible priority represents a complete sync.
418- lastCompleteSync = parsedDate ;
419- } else {
420- priorityStatusEntries . push ( { priority, hasSynced : true , lastSyncedAt : parsedDate } ) ;
421- }
422- }
423-
424- const hasSynced = lastCompleteSync != null ;
425421 const updatedStatus = new SyncStatus ( {
426422 ...this . currentStatus . toJSON ( ) ,
427- hasSynced,
428- priorityStatusEntries,
429- lastSyncedAt : lastCompleteSync
423+ ...coreStatusToJs ( parsed )
430424 } ) ;
431425
432426 if ( ! updatedStatus . isEqual ( this . currentStatus ) ) {
@@ -471,7 +465,9 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
471465 }
472466
473467 // Use the options passed in during connect, or fallback to the options set during database creation or fallback to the default options
474- resolvedConnectionOptions ( options ?: PowerSyncConnectionOptions ) : RequiredAdditionalConnectionOptions {
468+ protected resolvedConnectionOptions (
469+ options : CreateSyncImplementationOptions
470+ ) : CreateSyncImplementationOptions & RequiredAdditionalConnectionOptions {
475471 return {
476472 ...options ,
477473 retryDelayMs :
@@ -540,6 +536,8 @@ export abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncDB
540536 this . iterateListeners ( ( l ) => l . statusChanged ?.( this . currentStatus ) ) ;
541537 }
542538
539+ syncStream ( name : string , params ?: Record < string , any > ) { }
540+
543541 /**
544542 * Close the database, releasing resources.
545543 *
0 commit comments