diff options
Diffstat (limited to 'docs/apps.md')
| -rw-r--r-- | docs/apps.md | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/docs/apps.md b/docs/apps.md index 1cd6339..ef8cc1a 100644 --- a/docs/apps.md +++ b/docs/apps.md @@ -80,6 +80,39 @@ needs — a new app does not get a bespoke prop list. Notable ones: | `transportRef`, `gekRef` | refs to the live MNP transport and the imported group key | never state — a ref, so reconnects don't force a re-render of every app | | `mayUpload` | `memberUpload || isNodeAdmin`, computed once | Files' toolbar and Chat's composer both gate on it; a second derivation would eventually disagree with the first | +### 2b. The same app, rendered by the Search page + +Videos, Music and Photos are mounted twice: by `group-page.js` for one group, +and by `search-page.js` across every group the reader belongs to. The second +caller passes the same prop shape, and the difference lives entirely on the +**entries**, in underscore-prefixed fields the group page never sets: + +| Field | What it is | +|---|---| +| `groupId`, `groupName`, `groupOwner` | which group serves this entry | +| `_tRef`, `_gRef` | that group's transport and key — read as `entry._tRef \|\| transportRef`, which is why a single-group mount needs no special case | +| `_connGen` | bumped when that group reconnects; use it as a refetch key so a tile recovers instead of staying a spinner | +| `_sources` | every group that has this file, after the de-duplication below | + +**A file shared by two groups is one entry, not two** (`source-merge.js`, +`docs/refactoring-search.md`). Entries are folded on their content hash and one +source is resolved per *unit* — a film, a show, an album — using each app's own +grouping function to decide what a unit is. Two consequences for a new app: + +- if it renders a group name, use **`SourceTag`** from `group-name.js` rather + than `entry.groupName`: a merged entry has several groups and must say + `N sources` instead of naming one. Pass it the **whole unit** (a show's + episodes, an album's tracks), not the entry the card was drawn from — that + entry is usually chosen for its thumbnail, and would under-report; +- if it needs a merge unit key of its own, add a `<name>Units()` helper to + `search-page.js` that calls the app's **exported** grouping function. Never + re-derive the keys there: a copy keeps agreeing until one of them changes, + and the symptom is a show whose episodes stream from two different nodes. + +The Files explorer is deliberately **not** merged — there each group is a +top-level folder, and merging would remove a file from one of them. +`test_search_files_unmerged.py` refuses a build that changes this. + An app that needs **local** state (Files' `selecting`/`sortKey`/`currentPath`, for instance) owns it itself with `useState`, same as before the split. One thing worth keeping if you add a tab with a notion of "current location within @@ -160,8 +193,11 @@ registry, so a newly-registered app gets a checkbox for free. 5. **`webapp.py`'s `_ASSETS`** tuple: add the new file. This is the cache-busting hash's input list — a file imported by the page but missing here can change without the served URL changing, which is the exact bug - class `test_asset_versioning.py` exists for. Forgetting this step is - silent: nothing errors, a browser just keeps an old copy. + class `test_asset_versioning.py` exists for. Forgetting this step used to be + silent: nothing errors, a browser just keeps an old copy. It is now caught — + `test_every_static_script_participates_in_the_fingerprint` holds `_ASSETS` + to every `.js` in `static/` (`sw.js` excepted, unversioned on purpose). + Written after `source-merge.js` shipped missing from the list. 6. **Test coverage that scans the file set**: `test_hook_ordering.py` (`STATIC_FILES`) and `test_transport_contracts.py` (`test_no_setter_survives_the_state_it_belonged_to`, `SPLIT_FILES`) walk a |