@@ -2,31 +2,38 @@ import '@azure/core-asynciterator-polyfill';
22
33import { createBaseLogger , LogLevel , PowerSyncDatabase , SyncClientImplementation } from '@powersync/react-native' ;
44import React from 'react' ;
5- import { SupabaseStorageAdapter } from '../storage/SupabaseStorageAdapter' ;
65
7- import { type AttachmentRecord } from '@powersync/attachments' ;
6+ import {
7+ AttachmentQueue ,
8+ type AttachmentRecord ,
9+ ExpoFileSystemAdapter ,
10+ type WatchedAttachmentItem
11+ } from '@powersync/attachments' ;
812import { configureFts } from '../fts/fts_setup' ;
913import { KVStorage } from '../storage/KVStorage' ;
14+ import { SupabaseRemoteStorageAdapter } from '../storage/SupabaseRemoteStorageAdapter' ;
1015import { AppConfig } from '../supabase/AppConfig' ;
1116import { SupabaseConnector } from '../supabase/SupabaseConnector' ;
12- import { AppSchema } from './AppSchema' ;
13- import { PhotoAttachmentQueue } from './PhotoAttachmentQueue' ;
17+ import { AppSchema , TODO_TABLE } from './AppSchema' ;
1418
1519const logger = createBaseLogger ( ) ;
1620logger . useDefaults ( ) ;
1721logger . setLevel ( LogLevel . DEBUG ) ;
1822
1923export class System {
2024 kvStorage : KVStorage ;
21- storage : SupabaseStorageAdapter ;
2225 supabaseConnector : SupabaseConnector ;
2326 powersync : PowerSyncDatabase ;
24- attachmentQueue : PhotoAttachmentQueue | undefined = undefined ;
27+ photoAttachmentQueue : AttachmentQueue | undefined = undefined ;
2528
2629 constructor ( ) {
2730 this . kvStorage = new KVStorage ( ) ;
28- this . supabaseConnector = new SupabaseConnector ( this ) ;
29- this . storage = this . supabaseConnector . storage ;
31+ this . supabaseConnector = new SupabaseConnector ( {
32+ kvStorage : this . kvStorage ,
33+ supabaseUrl : AppConfig . supabaseUrl ,
34+ supabaseAnonKey : AppConfig . supabaseAnonKey
35+ } ) ;
36+
3037 this . powersync = new PowerSyncDatabase ( {
3138 schema : AppSchema ,
3239 database : {
@@ -50,17 +57,44 @@ export class System {
5057 */
5158
5259 if ( AppConfig . supabaseBucket ) {
53- this . attachmentQueue = new PhotoAttachmentQueue ( {
54- powersync : this . powersync ,
55- storage : this . storage ,
56- // Use this to handle download errors where you can use the attachment
57- // and/or the exception to decide if you want to retry the download
58- onDownloadError : async ( attachment : AttachmentRecord , exception : any ) => {
59- if ( exception . toString ( ) === 'StorageApiError: Object not found' ) {
60- return { retry : false } ;
61- }
60+ const localStorage = new ExpoFileSystemAdapter ( ) ;
61+ const remoteStorage = new SupabaseRemoteStorageAdapter ( {
62+ client : this . supabaseConnector . client ,
63+ bucket : AppConfig . supabaseBucket
64+ } ) ;
6265
63- return { retry : true } ;
66+ this . photoAttachmentQueue = new AttachmentQueue ( {
67+ db : this . powersync ,
68+ localStorage,
69+ remoteStorage,
70+ watchAttachments : ( onUpdate ) => {
71+ this . powersync . watch (
72+ `SELECT photo_id as id FROM ${ TODO_TABLE } WHERE photo_id IS NOT NULL` ,
73+ [ ] ,
74+ {
75+ onResult : ( result : any ) => {
76+ const attachments : WatchedAttachmentItem [ ] = ( result . rows ?. _array ?? [ ] ) . map ( ( row : any ) => ( {
77+ id : row . id ,
78+ fileExtension : 'jpg'
79+ } ) ) ;
80+ onUpdate ( attachments ) ;
81+ }
82+ }
83+ ) ;
84+ } ,
85+ errorHandler : {
86+ onDownloadError : async ( attachment : AttachmentRecord , error : Error ) => {
87+ if ( error . toString ( ) === 'StorageApiError: Object not found' ) {
88+ return false ; // Don't retry
89+ }
90+ return true ; // Retry
91+ } ,
92+ onUploadError : async ( attachment : AttachmentRecord , error : Error ) => {
93+ return true ; // Retry uploads by default
94+ } ,
95+ onDeleteError : async ( attachment : AttachmentRecord , error : Error ) => {
96+ return true ; // Retry deletes by default
97+ }
6498 }
6599 } ) ;
66100 }
@@ -70,8 +104,8 @@ export class System {
70104 await this . powersync . init ( ) ;
71105 await this . powersync . connect ( this . supabaseConnector , { clientImplementation : SyncClientImplementation . RUST } ) ;
72106
73- if ( this . attachmentQueue ) {
74- await this . attachmentQueue . init ( ) ;
107+ if ( this . photoAttachmentQueue ) {
108+ await this . photoAttachmentQueue . startSync ( ) ;
75109 }
76110
77111 // Demo using SQLite Full-Text Search with PowerSync.
0 commit comments