Files
Firelink/implementation_plan.md
T
NimBold 6b3753949b fix(downloads): support offline fallback drafts
- launch Firefox handoffs through authenticated reconnect
- preserve usable drafts when metadata lookup fails
- reject stale metadata results and retry failed rows only
2026-06-22 17:22:21 +03:30

149 lines
6.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Firefox Offline Handoff and Metadata Fallback Plan
## Constraints
- No Native Messaging, helper executable, background service, or Apple Developer account dependency.
- Firefox controls first-use external-protocol confirmation. Firelink cannot suppress it.
- First use requires user approval; Firefox may offer “Always allow this extension to open firelink links.”
- Automatic browser-download capture never launches Firelink and resumes Firefox unless `/download` confirms acceptance.
## 1. Firefox launch-and-reconnect flow
1. Add launch-only `firelink://launch`.
2. Manual action first sends original authenticated `/download` payload.
3. Launch fallback is allowed only when authenticated discovery finds no Firelink server.
- Never launch for `403`, other `4xx`, or a Firelink server returning `5xx`.
- A startup `503` may be retried within the existing startup deadline.
- Never retry an ambiguous POST failure after request transmission because delivery may already have happened.
4. Offline manual actions use one shared launch operation:
- Create one inactive `firelink://launch` tab.
- Queue immutable original payloads while startup is in progress.
- Poll authenticated `/ping` across `127.0.0.1:6412-6422` with bounded retries.
- Deliver every queued payload exactly once after startup.
- Close the launch tab only after all queued payloads reach a terminal result.
5. Success means authenticated `/download` returned success. Tab creation is never success.
6. Timeout/cancel:
- Stop after defined deadline.
- Close temporary tab where Firefox permits.
- Notify that Firelink was not opened and no download was added.
7. Store consecutive launch-timeout count and cooldown timestamp in `chrome.storage.local`.
- Reset both after successful startup delivery.
- During cooldown, do not open another protocol tab; show concise troubleshooting guidance.
8. Invalid pairing tokens never trigger protocol fallback.
## 2. Firefox first-use guidance
- README and popup explain first-use Firefox confirmation and “Always allow.”
- State clearly Firelink cannot bypass browser-controlled prompt.
- Repeated timeout guidance suggests confirming protocol permission, opening Firelink once, and checking installation.
## 3. Typed desktop deep links
Use a typed parser result:
- `Launch`
- `Add(Vec<String>)`
- `Invalid`
Rules:
- `firelink://launch` must contain exact scheme and host, with no username, password, port, path beyond `/`, query, or fragment.
- `Launch` restores/focuses window and never enters `CaptureUrls`.
- `firelink://add?url=...` keeps current external integration behavior.
- Unsupported schemes/hosts and malformed nested URLs return `Invalid`.
- Startup and already-running links use same dispatch function.
- Add URLs remain buffered in `DownloadCoordinator` until frontend listeners report ready.
## 4. Explicit metadata model
Each draft row has:
- Stable `id`
- Normalized `sourceUrl` identity
- `downloadUrl`, which metadata redirects may update
- Monotonic request `generation`
- Required status union: `loading | ready | metadata-error | invalid`
- Fallback filename and optional size bytes (`undefined` means unknown)
- Direct/media classification
- Optional successful metadata and selected media format
Malformed or unsupported URLs are `invalid`. Valid URLs whose metadata request fails remain `metadata-error`.
## 5. Parsing and enrichment separation
- Extract pure URL parsing/reconciliation helpers from modal.
- Normalize and deduplicate input by `sourceUrl`, preserving first occurrence order.
- Preserve existing rows, IDs, successful metadata, and selected formats.
- Create `loading` rows only for new valid URLs.
- Metadata results apply only when row ID, `sourceUrl`, and request generation still match.
- Save location, selection, and another rows result never restart metadata.
- Credential edits affect transfer credentials and future failed-row retries only. Ready metadata remains unchanged.
## 6. Failed-only refresh
- Refresh selects only `metadata-error` rows.
- Increment only those rows generations and mark only those rows `loading`.
- Preserve every successful row and selected format.
- Failed retry restores fallback row as `metadata-error`.
- Disable refresh when no failed rows exist.
## 7. Submission eligibility and fallback routing
Eligible: `ready`, `metadata-error`.
Blocking: `loading`, `invalid`.
- Start Downloads and Add to Queue share one eligibility helper.
- Unknown size stays `undefined`; display text is derived and `"Unknown"` is not persisted as size.
- Failed direct rows retain original URL, fallback filename, direct routing, credentials, mirrors, duplicate checks, and destination logic.
- Failed media rows retain `isMedia: true`, send no format selector, and use yt-dlp default selection.
- Remove redownload validation requiring a media selector; selector-less media items remain valid.
## 8. Add-window messaging
- Loading: “Waiting for metadata for N downloads.”
- Mixed: “N downloads ready; M will use fallback filename and unknown size.”
- All failed: “Metadata is unavailable. Downloads can still be added using fallback details.”
- Invalid: “Correct or remove N invalid URL(s) before continuing.”
- Failed rows remain visually distinct but usable.
## 9. Tests
### Extension
- Offline manual action opens `firelink://launch`, not `firelink://add`.
- Tab creation is not success.
- Authenticated discovery retries; original payload fields survive startup.
- Shared startup sends concurrent payloads once and closes tab after terminal delivery.
- Timeout/cancel notifies failure and records cooldown.
- Automatic capture never opens protocol tab.
- Invalid token and other server errors never launch.
- Ambiguous POST failure never resends.
### Desktop
- Exact launch restores without downloads.
- Add links still parse.
- Unsupported/malformed links reject.
- Startup/running dispatch match.
- Startup Add URLs wait for frontend readiness.
### Add window
- Pure helper tests cover reconciliation, stale generations, failed-only refresh, eligibility, fallback routing, unknown size, duplicate filenames, and destinations.
- Component-level behavior uses pure helpers where possible; no DOM test runtime is required unless interaction coverage cannot be expressed through helpers.
## 10. Acceptance and verification
Run:
```bash
npm run test
npm run build
(cd Extensions/Firefox && npm run check)
(cd src-tauri && cargo check)
(cd src-tauri && cargo test --all-targets)
```
Then perform Firefox offline and mixed/all-failed metadata acceptance scenarios from original plan.