11import { ILogger } from '@powersync/common' ;
22import { AttachmentContext } from './AttachmentContext.js' ;
3- import { EncodingType , LocalStorageAdapter } from './LocalStorageAdapter.js' ;
3+ import { LocalStorageAdapter } from './LocalStorageAdapter.js' ;
44import { RemoteStorageAdapter } from './RemoteStorageAdapter.js' ;
55import { AttachmentRecord , AttachmentState } from './Schema.js' ;
66import { SyncErrorHandler } from './SyncErrorHandler.js' ;
77
8- export class StorageService {
8+ /**
9+ * Orchestrates attachment synchronization between local and remote storage.
10+ * Handles uploads, downloads, deletions, and state transitions.
11+ */
12+ export class SyncingService {
913 context : AttachmentContext ;
1014 localStorage : LocalStorageAdapter ;
1115 remoteStorage : RemoteStorageAdapter ;
@@ -26,6 +30,13 @@ export class StorageService {
2630 this . errorHandler = errorHandler ;
2731 }
2832
33+ /**
34+ * Processes attachments based on their state (upload, download, or delete).
35+ * All updates are saved in a single batch after processing.
36+ *
37+ * @param attachments - Array of attachment records to process
38+ * @returns Promise that resolves when all attachments have been processed and saved
39+ */
2940 async processAttachments ( attachments : AttachmentRecord [ ] ) : Promise < void > {
3041 const updatedAttachments : AttachmentRecord [ ] = [ ] ;
3142 for ( const attachment of attachments ) {
@@ -51,6 +62,14 @@ export class StorageService {
5162 await this . context . saveAttachments ( updatedAttachments ) ;
5263 }
5364
65+ /**
66+ * Uploads an attachment from local storage to remote storage.
67+ * On success, marks as SYNCED. On failure, defers to error handler or archives.
68+ *
69+ * @param attachment - The attachment record to upload
70+ * @returns Updated attachment record with new state
71+ * @throws Error if the attachment has no localUri
72+ */
5473 async uploadAttachment ( attachment : AttachmentRecord ) : Promise < AttachmentRecord > {
5574 this . logger . info ( `Uploading attachment ${ attachment . filename } ` ) ;
5675 try {
@@ -79,9 +98,17 @@ export class StorageService {
7998 }
8099 }
81100
101+ /**
102+ * Downloads an attachment from remote storage to local storage.
103+ * Retrieves the file, converts to base64, and saves locally.
104+ * On success, marks as SYNCED. On failure, defers to error handler or archives.
105+ *
106+ * @param attachment - The attachment record to download
107+ * @returns Updated attachment record with local URI and new state
108+ */
82109 async downloadAttachment ( attachment : AttachmentRecord ) : Promise < AttachmentRecord > {
83110 try {
84- const fileBlob = await this . remoteStorage . downloadFile ( attachment ) ;
111+ const file = await this . remoteStorage . downloadFile ( attachment ) ;
85112
86113 const base64Data = await new Promise < string > ( ( resolve , reject ) => {
87114 const reader = new FileReader ( ) ;
@@ -90,7 +117,7 @@ export class StorageService {
90117 resolve ( reader . result ?. toString ( ) . replace ( / ^ d a t a : .+ ; b a s e 6 4 , / , '' ) || '' ) ;
91118 } ;
92119 reader . onerror = reject ;
93- reader . readAsDataURL ( fileBlob ) ;
120+ reader . readAsDataURL ( new File ( [ file ] , attachment . filename ) ) ;
94121 } ) ;
95122
96123 const localUri = this . localStorage . getLocalUri ( attachment . filename ) ;
@@ -114,6 +141,14 @@ export class StorageService {
114141 }
115142 }
116143
144+ /**
145+ * Deletes an attachment from both remote and local storage.
146+ * Removes the remote file, local file (if exists), and the attachment record.
147+ * On failure, defers to error handler or archives.
148+ *
149+ * @param attachment - The attachment record to delete
150+ * @returns Updated attachment record
151+ */
117152 async deleteAttachment ( attachment : AttachmentRecord ) : Promise < AttachmentRecord > {
118153 try {
119154 await this . remoteStorage . deleteFile ( attachment ) ;
@@ -141,6 +176,10 @@ export class StorageService {
141176 }
142177 }
143178
179+ /**
180+ * Performs cleanup of archived attachments by removing their local files and records.
181+ * Errors during local file deletion are logged but do not prevent record deletion.
182+ */
144183 async deleteArchivedAttachments ( ) : Promise < void > {
145184 const archivedAttachments = await this . context . getArchivedAttachments ( ) ;
146185 for ( const attachment of archivedAttachments ) {
0 commit comments