Skip to content

Attachments Support #68

Open
Open
@jurassix

Description

@jurassix

This issue is to act as a placeholder for work remaining to fully support Attachments.

The remaining issues are as follows:

  1. On replication to remote CouchDB where the local doc contains an attachment it should successfully sync the doc and attachment data. If doc contains an attachment sync fails.
  2. On replication from remote CouchDB were the remote doc contain an attachment it should successfully sync the doc and attachment data. If doc contains an attachment sync fails.

Considerations unique to ReactNative:

(Note: these following information is based on my observations, some accuracy may be missing, please correct where appropriate. I'm still learning how the ReactNative packager works.)

  1. ReactNative has 2 runtimes V8 in Debug and JSC in Release.
    1. During Debug (simulator build in Debug) the application is packaged targeting the browser (Chrome V8) and we have access to the window and DOM and other browser native implementations e.g. Blob
    2. During JSC Release (simulator build in Release) the application is packaged targeting JSC and we do not have access to the window and DOM. JSC isn't at feature parity with V8. Blob is replaced with node's Buffer.
  2. Most polyfills fallback to native browser when available, which causes some interesting results between Debug and Release.
  3. ReactNative only uses fetch
  4. PouchDB has many dependencies - adapters, plugins, utils - each of these are packages for node or browser. However, ReactNative packager always chooses the browser version during package resolution (based on my testing)

Research:

  1. This library currently has a hack during the postinstal phase, where the pouchdb-binary-utils/package.json is patched to force the ReactNative packager to chose the node versions of the library.
  2. If I remove the above hack locally:
    1. I can successfully get sync to work for all use cases, on iOS simulator in V8 Debug. This is due to the reliance on both this library and all Pouchdb dependencies choosing browser installs, and and native browser lib implementations, all the way down.
    2. During JSC release mode, on iOS simulator, I receive Blobs from the pouchdb-adapter-http, which in turn delegated to pouchdb-ajax. Since ReactNative runtime JSC has no support for FileReader/FileReaderSync we do not have a utility to transform a Blob to Buffer or Base64. more context here
      1. I believe we can get an ArrayBuffer in all cases instead of returning a Blob and be in a better situation. More research needed here.
      2. We also cannot opt for the the node version of pouchdb-ajax because it relies on request which will not work in ReactNative without hacks to expose additional core node modules.

Next Steps:

  1. I've been building out test cases for Attachments. All scenarios pass. This is due to our test suite being run in a fully node.js context and doesn't represent the ReactNative runtime. In the future it would be beneficial to extend coverage to more environment.
  2. I've currently forked both pouchdb-adapter-http and pouchdb-ajax and have created ReactNative versions of these and am experimenting with getting full support for both Debug and Release. For these versions I'm supporting only fetch and always returning ArrayBuffer never Blob. This is getting close. However, many tests are not passing locally.
  3. I believe if we can patch the above utilities then we will have full - or very close - support for Attachments in this library, for both the Debug and Release contexts.
  4. I am worried that this effort could snowball into to essentially forking PouchDB, but right now I'm not seeing the need for this.
  5. I could use some additional direction in terms of patching pouchdb-adapter-http. My current build hasn't made any changes except to the new pouchdb-ajax delegation library. There is currently no way to provide strategies without having direct access to the PouchDB instance. Long term this will not be maintainable without a strategy pattern in place at plugin registry. Also, there may be much better ways of injecting a different implementation, will need some direction from @nolanlawson e.g.
const db = new PouchDB('local');
db._ajax = fetchCore;

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions