mirror of
https://github.com/nimbold/Firelink.git
synced 2026-07-27 12:29:29 +00:00
6b3753949b
- launch Firefox handoffs through authenticated reconnect - preserve usable drafts when metadata lookup fails - reject stale metadata results and retry failed rows only
149 lines
6.5 KiB
Markdown
149 lines
6.5 KiB
Markdown
# 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 row’s 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.
|