-
Notifications
You must be signed in to change notification settings - Fork 61
Update attachment package #735
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
🦋 Changeset detectedLatest commit: 9812964 The changes in this PR will be included in the next version bump. This PR includes changesets to release 9 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
stevensJourney
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a good improvement so far. I've added some comments for some items I spotted.
packages/attachments/src/storageAdapters/NodeFileSystemAdapter.ts
Outdated
Show resolved
Hide resolved
- Added `getAttachment` method to retrieve an attachment by ID in AttachmentContext. - Updated `upsertAttachment` to handle null values for optional fields. - Introduced `generateAttachmentId` method in AttachmentQueue for generating unique IDs. - Modified `watchActiveAttachments` to accept a throttle parameter. - Added `deleteFile` method to have attachment deletion. - Updated tests to cover new functionality and ensure reliability.
…ttachment sync operations - Added AttachmentErrorHandler interface to manage download, upload, and delete errors for attachments. - Updated AttachmentQueue and SyncingService to utilize the new error handler. - Enhanced tests to verify error handling behavior during attachment sync processes.
671e23a to
bea28d9
Compare
bea28d9 to
e42ae45
Compare
… across the react-native-web demo
# Conflicts: # pnpm-lock.yaml
stevensJourney
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some comments. Overall the APIs and code looks good so far.
demos/react-native-supabase-todolist/library/powersync/system.ts
Outdated
Show resolved
Hide resolved
packages/react-native/package.json
Outdated
| "dependencies": { | ||
| "@powersync/common": "workspace:*", | ||
| "@powersync/react": "workspace:*", | ||
| "expo-file-system": "18.0.12", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this would not work on non-Expo React Native projects? One would need to confirm this dependency does not cause any issues on bare React native projects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It requires an expo project unfortunately. But, currently looking at @dr.pogodin/react-native-fs an active fork of react-native-fs, which works on native.
One question about including it as a direct dependency. I was thinking of going the dynamic import + optional peer dependency route (similar to react-native-quick-sqlite), you see any potential pitfalls?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've seen before, in the past, that nested direct dependencies sometimes aren't detected and installed correctly in the Expo build process. This might have changed at some point though.
Generally, an optional peer dependency would follow our current patterns. Dynamic imports with Metro have been a pain in the past, however if one follows the same patters as React Native Quick SQLite, I think we should be fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I kept both, just for better coverage. I think catering for both Expo and vanilla React Native projects would be worthwhile. I understand there is a maintenance burden with supporting both adapters.
The vanilla implementation works on Expo as well, so let me know if you think this is redundant.
stevensJourney
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed a few items in this review, but I do think this is looking good.
| * @param onUpdate - Callback to invoke when attachment references change | ||
| * @throws Error indicating this method must be implemented by the user | ||
| */ | ||
| watchAttachments(onUpdate: (attachment: WatchedAttachmentItem[]) => Promise<void>, signal: AbortSignal): void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks a bit weird as a function definition with no actual implementation. This should probably be a class property instead (since it's assigned in the constructor)
| /** Adapter for remote file storage operations */ | ||
| remoteStorage: RemoteStorageAdapter; | ||
|
|
||
| /** @deprecated Directory path for storing attachments */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is a new version of the implementation which originates from a new source (the SDK packages themselves). I don't think we need to be deprecating things at this point - rather remove them.
| */ | ||
| export class AttachmentQueue { | ||
| /** Timer for periodic synchronization operations */ | ||
| periodicSyncTimer?: ReturnType<typeof setInterval>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default here for these class members is public - which I think we should avoid for some of these items. For items which make sense to be public, maybe consider making them readonly or clearly handle/document their update behaviour.
| this.syncThrottleDuration = syncThrottleDuration; | ||
| this.archivedCacheLimit = archivedCacheLimit; | ||
| this.downloadAttachments = downloadAttachments; | ||
| this.context = new AttachmentContext(db, tableName, logger ?? db.logger, archivedCacheLimit); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One of the main purposes of the AttachmentService is to provide a locked/exclusive access to an AttachmentContext. Creating a context manually here defeats that purpose, please add a withContext method to AttachmentService which provides leased access to the context.
| tableName?: string; | ||
|
|
||
| /** Logger instance for diagnostic information */ | ||
| logger?: ILogger; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can remove the optionality of this member since the constructor provides a default
| "homepage": "https://docs.powersync.com/", | ||
| "peerDependencies": { | ||
| "@journeyapps/react-native-quick-sqlite": "^2.4.9", | ||
| "@dr.pogodin/react-native-fs": "^2.36.1", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should probably also be devDependencies. This probably currently works since the packages are being hoisted from the demos. This will soon no-longer be the case.
| 'js-logger', | ||
| 'react-native', | ||
| 'react', | ||
| '@dr.pogodin/react-native-fs', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably also include expo-filesystem here?
| import { decode as decodeBase64, encode as encodeBase64 } from 'base64-arraybuffer'; | ||
| import { AttachmentData, EncodingType, LocalStorageAdapter } from '@powersync/common'; | ||
|
|
||
| try { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to lazy load RNFS in the constructor of ReactNativeFileSystemStorageAdapter instead of doing this globally?
This a port of the Swift, Dart and Kotlin attachment's API to the JS SDK.
This addresses the following issues #715 and #714 by adding the
meta_datacolumn to the table and persisting it in the attachments table.It is currently still a work-in-progress so there are a couple things that still needs to be done: