Skip to content

Conversation

@joshua-journey-apps
Copy link

@joshua-journey-apps joshua-journey-apps commented Oct 7, 2025

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_data column 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:

  • Move attachment package to common
    • Move Node adapter under Node package
    • Move indexDB adapter under Web package
    • Move Expo adapter under RN package
  • Update demos
  • Improve testing
  • Update the README
  • Implement sync throttling
  • Complete clearing archived attachments
  • Removing some holdovers from the previous implementation
    • Supported file data format

@changeset-bot
Copy link

changeset-bot bot commented Oct 7, 2025

🦋 Changeset detected

Latest commit: d86799a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 9 packages
Name Type
@powersync/react-native Minor
@powersync/common Minor
@powersync/node Minor
@powersync/web Minor
@powersync/attachments Patch
@powersync/adapter-sql-js Patch
@powersync/op-sqlite Patch
@powersync/tanstack-react-query Patch
@powersync/diagnostics-app Patch

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

Copy link
Collaborator

@stevensJourney stevensJourney left a 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.

joshuabrink and others added 17 commits October 27, 2025 15:49
- 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.
@joshuabrink joshuabrink force-pushed the attachment-package-refactor branch from 671e23a to bea28d9 Compare November 12, 2025 09:15
@joshuabrink joshuabrink force-pushed the attachment-package-refactor branch from bea28d9 to e42ae45 Compare November 12, 2025 09:15
@joshuabrink joshuabrink marked this pull request as ready for review November 28, 2025 13:10
Copy link
Collaborator

@stevensJourney stevensJourney left a 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.

localStorage,
remoteStorage,
watchAttachments: (onUpdate) => {
this.powersync.watch(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like we would need a way to dispose of the watched queries here. e.g. if the AttachmentsQueue was to be closed (or sync stopped), we'd need to stop these queries.

"type": "git",
"url": "git+https://github.com/powersync-ja/powersync-js.git"
},
"deprecated": "This package has been merged into @powersync/common. Please use @powersync/common instead.",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should recommend using the various SDK packages directly instead? We typically don't require users to install @powersync/common directly for most cases.

state: AttachmentState.SYNCED
});
} else {
// The localURI should be set if the record was meant to be downloaded
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// The localURI should be set if the record was meant to be downloaded
// The localURI should be set if the record was meant to be uploaded

* - Archives attachments with missing local files that haven't been uploaded
* - Requeues synced attachments for download if their local files are missing
*/
verifyAttachments = async (): Promise<void> => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For my curiosity, whats the reason for this being an arrow function?

hasSynced: true
};
} catch (error) {
const shouldRetry = this.errorHandler?.onUploadError(attachment, error) ?? false;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the default here should be true. We only want to skip retries if the errorHandler explicitly says to do so.

@@ -0,0 +1,481 @@
import { describe, expect, it, vi } from 'vitest';
import { vol } from 'memfs';
import { PowerSyncDatabase, Schema, Table, column, NodeFileSystemAdapter } from '../../node';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be easier to just have these tests in the node package's unit tests.

"dependencies": {
"@powersync/common": "workspace:*",
"@powersync/react": "workspace:*",
"expo-file-system": "18.0.12",
Copy link
Collaborator

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants