@jsenv/navi 0.29.56 → 0.29.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -70,7 +70,8 @@ consistency across the app, not from any single call site.
70
70
  - `docs/list_refresh.md` — what a write sends back to the network and what stays
71
71
  on screen meanwhile: stale data returned by `useAsyncData({ loading: true })`,
72
72
  what updates from a response without any request, `rerunOn` and its defaults,
73
- and how a paginated `<List.Items>` re-reads its slices without disappearing.
73
+ and how a paginated `<List.Items>` re-reads its slices without disappearing,
74
+ including on its way back from a screen that unmounted it.
74
75
  Read it before adding verbs to `rerunOn`, hiding a list on `loading`, or
75
76
  remounting a list with a `key` to refresh it.
76
77
  - `docs/error_handling.md` — the two kinds of error and how navi keeps them
@@ -69,10 +69,10 @@ list containing it drops it too.
69
69
 
70
70
  ## A paginated list stays on screen too
71
71
 
72
- A `<List.Items>` reading through `GET_RANGE` holds the slices it received
73
- places in a collection, not a list of ids so nothing the store does can fix
74
- them: a row that changed tab, or one that was deleted, moves every row after it
75
- one rank up, and only the collection knows who fills the last place.
72
+ A `<List.Items>` reading through `GET_RANGE` draws places in a collection, not
73
+ a list of ids, so nothing the store does can fix them: a row that changed tab,
74
+ or one that was deleted, moves every row after it one rank up, and only the
75
+ collection knows who fills the last place.
76
76
 
77
77
  It is told, and it re-reads by itself:
78
78
 
@@ -84,7 +84,7 @@ It is told, and it re-reads by itself:
84
84
  />
85
85
  ```
86
86
 
87
- The reader keeps no value, so there is nothing to rerun; what it has is a
87
+ The reader keeps no response, so there is nothing to rerun; what it has is a
88
88
  signal, bumped by the verbs `rerunOn.GET_RANGE` lists (`["POST", "DELETE"]` by
89
89
  default — `DELETE` is in there precisely because the store cannot fix places).
90
90
  A run hearing it asks again **for the window it is drawing**, and keeps drawing
@@ -108,11 +108,43 @@ itself: it is the one rendering the row, so it draws it loading, muted, or not
108
108
  at all. The run is not told about rows, only about the collection.
109
109
 
110
110
  ```jsx
111
- // ✗ remounting the run to refresh it: every row on screen becomes a skeleton
112
- // again, and the list reopens where it opens, not where it was being read
111
+ // ✗ remounting the run to refresh it: the list reopens where it opens, not
112
+ // where it was being read, and the reader is asked again for that window
113
113
  <List.Items key={`${scope}:${moved}`} … />
114
114
  ```
115
115
 
116
+ ## Leaving the screen and coming back
117
+
118
+ A router renders one branch: opening a row unmounts the list that led to it.
119
+ Coming back draws the rows from before, with no first load, because the reader
120
+ keeps the collection's **composition** — which rank holds which id, and how many
121
+ ranks there are — for each set of resolved bound params:
122
+
123
+ ```
124
+ GAME.GET_RANGE { scope: "thread" } → { count: 412, byIndex: 0 → "W-ABC", 1 → … }
125
+ GAME.GET_RANGE { radar: "R-42" } → { count: 18, byIndex: … }
126
+ ```
127
+
128
+ Ids, never rows: the rows are in the store already, shared and live, and a row
129
+ dropped from the store simply stops resolving — a composition cannot hold a
130
+ stale copy of anything.
131
+
132
+ A run that finds a composition takes the `refreshing` line of the table above
133
+ rather than the loading one: the rows are on screen while it asks again for the
134
+ window it draws. So the two lists an app cannot tell apart from the outside —
135
+ one reading `GET_MANY`, one reading `GET_RANGE` — behave the same on the way
136
+ back.
137
+
138
+ What a composition is about is the **values** its params hold, not the reader
139
+ instance: `GET_RANGE.bindParams({ scope: "thread" })` called from two places
140
+ reads and writes the same one (and gives back the same reader, memoized the way
141
+ an action's `bindParams` is).
142
+
143
+ The rest follows the rules already stated: a verb in `rerunOn.GET_RANGE`, or
144
+ `reader.invalidate()`, drops the compositions — they stand for an order that is
145
+ gone — and `memoryBudget` (1000 ranks by default) trims the ranks far from any
146
+ window, which are asked for again if the user goes back to them.
147
+
116
148
  ## `rerunOn`, verb by verb
117
149
 
118
150
  `rerunOn` says which verbs invalidate this resource's `GET` / `GET_MANY` /
package/docs/resource.md CHANGED
@@ -98,14 +98,20 @@ makes a change detectable), so the one the list is holding is the one it was
98
98
  given. Relations are not concerned: they are keyed by owner, and a row reading
99
99
  `game.candidates` reads the shared collection whatever object carries it.
100
100
 
101
- `GET_RANGE` is a **reader, not an action**. It keeps no value and takes no place
102
- in the rerun graph, which is what makes it usable per slice:
101
+ `GET_RANGE` is a **reader, not an action**. It keeps no response and takes no
102
+ place in the rerun graph, which is what makes it usable per slice:
103
103
 
104
104
  - the list already holds the slices it received and glues them back together —
105
105
  a second memory holding one of them would fight it;
106
106
  - a `POST` invalidating "the collection" would otherwise send every slice ever
107
107
  loaded back to the network at once.
108
108
 
109
+ What it keeps instead is the collection's composition — which rank holds which
110
+ id, and how many ranks there are, per resolved bound params — so a list drawing
111
+ this collection again after its screen went away finds it drawn and revalidates
112
+ it rather than starting over
113
+ ([list_refresh.md](./list_refresh.md#leaving-the-screen-and-coming-back)).
114
+
109
115
  What it does not give is membership: an item that leaves the collection stays on
110
116
  screen until the rows are asked for again. Give the screen its own way to ask
111
117
  (a refresh gesture, a `key` on the run).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/navi",
3
- "version": "0.29.56",
3
+ "version": "0.29.57",
4
4
  "type": "module",
5
5
  "description": "Library of components including navigation to create frontend applications",
6
6
  "repository": {