Skip to content

Commit 6840fb0

Browse files
committed
Rename storage -> syncing service
1 parent 643289d commit 6840fb0

File tree

3 files changed

+49
-10
lines changed

3 files changed

+49
-10
lines changed

packages/attachments/src/AttachmentQueue.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@ import { AttachmentContext } from './AttachmentContext.js';
33
import { LocalStorageAdapter } from './LocalStorageAdapter.js';
44
import { RemoteStorageAdapter } from './RemoteStorageAdapter.js';
55
import { ATTACHMENT_TABLE, AttachmentRecord, AttachmentState } from './Schema.js';
6-
import { StorageService } from './StorageService.js';
6+
import { SyncingService } from './SyncingService.js';
77
import { WatchedAttachmentItem } from './WatchedAttachmentItem.js';
88
import { AttachmentService } from './AttachmentService.js';
99

1010
export class AttachmentQueue {
1111
periodicSyncTimer?: ReturnType<typeof setInterval>;
1212
context: AttachmentContext;
13-
storageService: StorageService;
13+
syncingService: SyncingService;
1414
localStorage: LocalStorageAdapter;
1515
remoteStorage: RemoteStorageAdapter;
1616
attachmentsDirectory?: string;
@@ -50,7 +50,7 @@ export class AttachmentQueue {
5050
this.localStorage = localStorage;
5151
this.watchAttachments = watchAttachments;
5252
this.tableName = tableName;
53-
this.storageService = new StorageService(this.context, localStorage, remoteStorage, logger ?? db.logger);
53+
this.syncingService = new SyncingService(this.context, localStorage, remoteStorage, logger ?? db.logger);
5454
this.attachmentService = new AttachmentService(tableName, db);
5555
this.syncIntervalMs = syncIntervalMs;
5656
this.syncThrottleDuration = syncThrottleDuration;
@@ -163,8 +163,8 @@ export class AttachmentQueue {
163163
async syncStorage(): Promise<void> {
164164
const activeAttachments = await this.context.getActiveAttachments();
165165
await this.localStorage.initialize();
166-
await this.storageService.processAttachments(activeAttachments);
167-
await this.storageService.deleteArchivedAttachments();
166+
await this.syncingService.processAttachments(activeAttachments);
167+
await this.syncingService.deleteArchivedAttachments();
168168
}
169169

170170
async stopSync(): Promise<void> {

packages/attachments/src/StorageService.ts renamed to packages/attachments/src/SyncingService.ts

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
import { ILogger } from '@powersync/common';
22
import { AttachmentContext } from './AttachmentContext.js';
3-
import { EncodingType, LocalStorageAdapter } from './LocalStorageAdapter.js';
3+
import { LocalStorageAdapter } from './LocalStorageAdapter.js';
44
import { RemoteStorageAdapter } from './RemoteStorageAdapter.js';
55
import { AttachmentRecord, AttachmentState } from './Schema.js';
66
import { 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(/^data:.+;base64,/, '') || '');
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) {

packages/attachments/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ export * from './storageAdapters/NodeFileSystemAdapter.js';
44
export * from './storageAdapters/IndexDBFileSystemAdapter.js';
55
export * from './RemoteStorageAdapter.js';
66
export * from './AttachmentContext.js';
7-
export * from './StorageService.js';
7+
export * from './SyncingService.js';
88
export * from './AttachmentQueue.js';

0 commit comments

Comments
 (0)