mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-10-19 07:42:31 +00:00
Merge pull request #1094 from vrtmrz/fix/issue-1020-fast-fetch-transport
Fall back to Standard Fetch for CouchDB's internal request API
This commit is contained in:
@@ -0,0 +1,78 @@
|
|||||||
|
# Architectural Decision Record: Fast Fetch Transport Eligibility
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
Fast Fetch accelerates Fast Setup (Simple Fetch) by reading bounded pages from
|
||||||
|
CouchDB's continuous changes feed. It consumes each response incrementally,
|
||||||
|
persists documents while the page is still arriving, and cancels the underlying
|
||||||
|
request when the page completes or fails.
|
||||||
|
|
||||||
|
The CouchDB setting `useRequestAPI`, labelled 'Use Internal API', routes ordinary
|
||||||
|
replication through Obsidian's `requestUrl` API to avoid browser CORS
|
||||||
|
restrictions. This API exposes a completed response as text, JSON, or an
|
||||||
|
`ArrayBuffer`; it does not expose the network response progressively or accept
|
||||||
|
the Fetch API's `AbortSignal`. Wrapping its result in a `Response` does not
|
||||||
|
restore those transport properties.
|
||||||
|
|
||||||
|
Custom headers can cause a browser preflight, and an authenticating proxy may
|
||||||
|
reject that preflight before the requested header values are sent. Custom
|
||||||
|
headers do not, however, make Fast Fetch intrinsically incompatible. A server
|
||||||
|
with correctly configured CORS can accept the same headers through the ordinary
|
||||||
|
Fetch API and retain streaming behaviour.
|
||||||
|
|
||||||
|
Ordinary PouchDB replication has a different response contract. Standard Fetch
|
||||||
|
uses finite batches, while LiveSync uses long-poll responses whose change
|
||||||
|
payload is bounded by the replication batch size. Both can process each response
|
||||||
|
after it has completed and do not depend on progressively reading a
|
||||||
|
document-bearing continuous feed.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
Fast Fetch requires a Fetch-compatible transport which exposes the response
|
||||||
|
body progressively and honours request cancellation.
|
||||||
|
|
||||||
|
When `useRequestAPI` is enabled for a CouchDB remote, Fast Fetch falls back to
|
||||||
|
Standard Fetch before entering the Fast Fetch activity or resetting the local
|
||||||
|
database through the Fast Fetch path. The presence of custom headers alone does
|
||||||
|
not disable Fast Fetch. Once Standard Fetch resets the local database, it
|
||||||
|
invalidates any retained Fast Fetch checkpoint for that database.
|
||||||
|
|
||||||
|
Commonlib's Rebuilder owns this eligibility decision because it owns both Fast
|
||||||
|
Fetch and the existing Standard Fetch fallback. The streaming implementation
|
||||||
|
does not receive Obsidian's buffered request adapter, and LiveSync does not add
|
||||||
|
proxy-specific or Cloudflare-specific policy.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
- Initial retrieval through Standard Fetch may be slower and issue more HTTP
|
||||||
|
requests because PouchDB uses the configured batch size, document retrieval,
|
||||||
|
and checkpoint operations. The decision does not assume that `requestUrl` is
|
||||||
|
faster; its benefit here is compatibility with connections which browser CORS
|
||||||
|
would otherwise reject.
|
||||||
|
- LiveSync remains supported with `useRequestAPI`. Its HTTP adapter uses
|
||||||
|
long-poll responses whose change payload is bounded by the replication batch
|
||||||
|
size, rather than the document-bearing stream required by Fast Fetch.
|
||||||
|
- A user whose server accepts the configured custom headers through correct
|
||||||
|
CORS handling can leave `useRequestAPI` disabled and continue to use Fast
|
||||||
|
Fetch.
|
||||||
|
- The decision can be revisited if Obsidian provides a progressively readable,
|
||||||
|
cancellable internal request API, or if a separately designed buffered
|
||||||
|
transport establishes explicit payload bounds and equivalent cancellation
|
||||||
|
semantics.
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
Commonlib unit tests verify that `useRequestAPI` selects only the existing
|
||||||
|
Standard Fetch activity, does not invoke Streaming Fetch, and invalidates any
|
||||||
|
retained Fast Fetch checkpoint after the local database is reset. Existing
|
||||||
|
tests continue to verify that custom headers are passed to Fast Fetch when
|
||||||
|
`useRequestAPI` is disabled.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
- [Fast Fetch Persistence and Completion Semantics](2026_08_fast_fetch_persistence_and_completion.md)
|
||||||
|
- [Apache CouchDB changes-feed API](https://docs.couchdb.org/en/stable/api/database/changes.html)
|
||||||
Generated
+4
-4
@@ -23,7 +23,7 @@
|
|||||||
"@smithy/types": "^4.14.3",
|
"@smithy/types": "^4.14.3",
|
||||||
"@smithy/util-retry": "^4.4.5",
|
"@smithy/util-retry": "^4.4.5",
|
||||||
"@vrtmrz/browser-ui-kit": "0.1.0",
|
"@vrtmrz/browser-ui-kit": "0.1.0",
|
||||||
"@vrtmrz/livesync-commonlib": "0.1.9",
|
"@vrtmrz/livesync-commonlib": "0.1.10",
|
||||||
"@vrtmrz/obsidian-plugin-kit": "0.1.3",
|
"@vrtmrz/obsidian-plugin-kit": "0.1.3",
|
||||||
"@vrtmrz/ui-interactions": "0.1.2",
|
"@vrtmrz/ui-interactions": "0.1.2",
|
||||||
"diff-match-patch": "^1.0.5",
|
"diff-match-patch": "^1.0.5",
|
||||||
@@ -4775,9 +4775,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@vrtmrz/livesync-commonlib": {
|
"node_modules/@vrtmrz/livesync-commonlib": {
|
||||||
"version": "0.1.9",
|
"version": "0.1.10",
|
||||||
"resolved": "https://registry.npmjs.org/@vrtmrz/livesync-commonlib/-/livesync-commonlib-0.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/@vrtmrz/livesync-commonlib/-/livesync-commonlib-0.1.10.tgz",
|
||||||
"integrity": "sha512-qacNUbRAqt32j756XTTdI5K+/co8oc2BKjzsUAhEsDHC8tc18q4a3cQrUHNJuxYO+nYnx0FKhf9lHMZcCX+Scg==",
|
"integrity": "sha512-1t1e8EPM2fuIbC107jJQXbSivWXcspD7kR/3AOgT29O9E5UbGFZR6vj1f84D6vOe8BiHhv8Ng9GvrCV6U+gGXg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/client-s3": "^3.808.0",
|
"@aws-sdk/client-s3": "^3.808.0",
|
||||||
|
|||||||
+1
-1
@@ -177,7 +177,7 @@
|
|||||||
"@smithy/types": "^4.14.3",
|
"@smithy/types": "^4.14.3",
|
||||||
"@smithy/util-retry": "^4.4.5",
|
"@smithy/util-retry": "^4.4.5",
|
||||||
"@vrtmrz/browser-ui-kit": "0.1.0",
|
"@vrtmrz/browser-ui-kit": "0.1.0",
|
||||||
"@vrtmrz/livesync-commonlib": "0.1.9",
|
"@vrtmrz/livesync-commonlib": "0.1.10",
|
||||||
"@vrtmrz/obsidian-plugin-kit": "0.1.3",
|
"@vrtmrz/obsidian-plugin-kit": "0.1.3",
|
||||||
"@vrtmrz/ui-interactions": "0.1.2",
|
"@vrtmrz/ui-interactions": "0.1.2",
|
||||||
"diff-match-patch": "^1.0.5",
|
"diff-match-patch": "^1.0.5",
|
||||||
|
|||||||
@@ -12,6 +12,13 @@ Earlier releases remain available in the 0.25 release history and the legacy rel
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### Setup and compatibility
|
||||||
|
|
||||||
|
#### Fixed
|
||||||
|
|
||||||
|
- Fast Setup now uses Standard Fetch when CouchDB's 'Use Internal API' setting is enabled, avoiding a streaming request path which Obsidian's buffered API cannot support (#1020).
|
||||||
|
- Custom headers alone continue to use Fast Fetch when browser CORS permits them; Standard Fetch clears any obsolete Fast Fetch checkpoint after resetting the local database.
|
||||||
|
|
||||||
### Synchronisation and storage
|
### Synchronisation and storage
|
||||||
|
|
||||||
#### Fixed
|
#### Fixed
|
||||||
|
|||||||
Reference in New Issue
Block a user