@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.
- package/dist/jsenv_navi.js +146 -25
- package/dist/jsenv_navi.js.map +9 -5
- package/docs/AI_INSTRUCTIONS.md +2 -1
- package/docs/list_refresh.md +39 -7
- package/docs/resource.md +8 -2
- package/package.json +1 -1
package/docs/AI_INSTRUCTIONS.md
CHANGED
|
@@ -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
|
package/docs/list_refresh.md
CHANGED
|
@@ -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`
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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
|
|
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:
|
|
112
|
-
//
|
|
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
|
|
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).
|