@jsenv/navi 0.29.521 → 0.29.523
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/dev/jsenv_navi.js +144 -49
- package/dist/dev/jsenv_navi.js.map +16 -16
- package/dist/jsenv_navi.js +144 -49
- package/dist/jsenv_navi.js.map +16 -16
- package/docs/AI_INSTRUCTIONS.md +7 -5
- package/docs/actions.md +42 -4
- package/docs/data_states.md +8 -0
- package/docs/drag_to_travel.md +16 -6
- package/docs/navigation.md +17 -0
- package/docs/resource.md +38 -0
- package/package.json +2 -2
package/docs/AI_INSTRUCTIONS.md
CHANGED
|
@@ -83,12 +83,14 @@ start when unsure which export solves a problem.
|
|
|
83
83
|
|
|
84
84
|
### Data
|
|
85
85
|
|
|
86
|
-
- `actions.md` — calling versus binding, a
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
- `actions.md` — calling versus binding, what a binding holds while its params
|
|
87
|
+
move (`inheritData`), a failing run rejects, reading is not running
|
|
88
|
+
(`{ run: true }` is the fallback), `action` versus `uiAction`, an action and a
|
|
89
|
+
command on one press. Before running an action from a component.
|
|
89
90
|
- `resource.md` — `resource()` and its relations (never an `op` discriminator),
|
|
90
|
-
`GET_RANGE` (its inclusive `end`,
|
|
91
|
-
|
|
91
|
+
what each read shows while its params move, `GET_RANGE` (its inclusive `end`,
|
|
92
|
+
the count for the screen around the list, a question following a search
|
|
93
|
+
field), a search as the same `GET_MANY`, `withParams()` scopes and
|
|
92
94
|
`dependencies`, `persist` (and `keepPageOnScreen` for the page on screen), a
|
|
93
95
|
function versus the verb's instance. Before writing a resource, and before
|
|
94
96
|
caching a response yourself.
|
package/docs/actions.md
CHANGED
|
@@ -22,6 +22,7 @@ them by hand — see [resource.md](./resource.md).
|
|
|
22
22
|
|
|
23
23
|
- [Params: `bindParams`, and calling the action](#params-bindparams-and-calling-the-action)
|
|
24
24
|
- [The answer is kept on the instance that ran](#the-answer-is-kept-on-the-instance-that-ran)
|
|
25
|
+
- [While the next answer comes](#while-the-next-answer-comes)
|
|
25
26
|
- [Nothing to ask, and coming back](#nothing-to-ask-and-coming-back)
|
|
26
27
|
- [The in-between states of a gesture are real params](#the-in-between-states-of-a-gesture-are-real-params)
|
|
27
28
|
- [Running: `run`, `rerun`, `prerun`, `reset`](#running-run-rerun-prerun-reset)
|
|
@@ -112,9 +113,11 @@ A request that follows typing — the suggestions under an address field — is
|
|
|
112
113
|
this binding, never the field's `action`: a field whose action runs is busy,
|
|
113
114
|
and a busy field is read-only, so the person could not go on typing.
|
|
114
115
|
`actionDebounce` delays an action that saves what was typed. Such a request,
|
|
115
|
-
written with a plain `createAction`,
|
|
116
|
-
([
|
|
117
|
-
|
|
116
|
+
written with a plain `createAction`, declares that its previous suggestions
|
|
117
|
+
stand in ([below](#while-the-next-answer-comes)), and has no verb for the
|
|
118
|
+
network policy to see ([network_policy.md](./network_policy.md)): offline, its
|
|
119
|
+
params say there is nothing to ask (`undefined`,
|
|
120
|
+
[below](#nothing-to-ask-and-coming-back)).
|
|
118
121
|
`src/control/demos/integration/0_address_autocomplete_demo.html` is this shape.
|
|
119
122
|
|
|
120
123
|
### The answer is kept on the instance that ran
|
|
@@ -138,13 +141,48 @@ verb — `computed(() => ME.GET.dataSignal.value)` — only works for a verb
|
|
|
138
141
|
something runs **directly**, with no params; anything else derives from the
|
|
139
142
|
instance: `computed(() => COUNTS.dataSignal.value)`.
|
|
140
143
|
|
|
144
|
+
### While the next answer comes
|
|
145
|
+
|
|
146
|
+
A binding moving to new params lands on an instance with no answer yet: `data`
|
|
147
|
+
is `undefined` until its own arrives, and the screen draws its wait. The previous
|
|
148
|
+
answer would be about something else — a club's podium under the name of the
|
|
149
|
+
department just pressed, one person's partners on another's profile — and nothing
|
|
150
|
+
would give it away: it reads as data, it only shows on a slow network, and it
|
|
151
|
+
fixes itself when the answer lands.
|
|
152
|
+
|
|
153
|
+
Another answer to **the same question** is different: results refined by a
|
|
154
|
+
keystroke, a window recentred along a list, a thread read again because it grew.
|
|
155
|
+
A blank between two of those is the only thing wrong on the screen, and the
|
|
156
|
+
action says so:
|
|
157
|
+
|
|
158
|
+
```js
|
|
159
|
+
const searchAddresses = createAction(search, { inheritData: true });
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
The new instance then starts on what the previous one held, its failure included,
|
|
163
|
+
and `loading` says a newer answer is coming. A resource declares this for each of
|
|
164
|
+
its reads: one item starts on nothing, a list hands over
|
|
165
|
+
([resource.md](./resource.md#what-a-read-shows-while-its-params-move)). When one
|
|
166
|
+
action serves both kinds of screen, a binding says it for itself, in either
|
|
167
|
+
direction:
|
|
168
|
+
|
|
169
|
+
```js
|
|
170
|
+
routeAction(AUTHOR_PAGE, VIDEOS, () => ({ author: authorSignal.value }), {
|
|
171
|
+
inheritData: false,
|
|
172
|
+
});
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Only a binding following a signal moves. Plain params make an instance that stays
|
|
176
|
+
what it is, and hand nothing over.
|
|
177
|
+
|
|
141
178
|
### Nothing to ask, and coming back
|
|
142
179
|
|
|
143
180
|
A binding has nothing to ask while its params as a whole are `undefined` or
|
|
144
181
|
`null` — a question computed from a form still missing a field.
|
|
145
182
|
`{ id: undefined }` is not that: it is a question, and it is asked. With nothing
|
|
146
183
|
to ask, the binding reads an instance holding nothing, idle: no data, no wait.
|
|
147
|
-
|
|
184
|
+
An answer declared to stand in does so only while a newer one is coming, and none
|
|
185
|
+
is.
|
|
148
186
|
|
|
149
187
|
What the previous params got stays on the instance that ran. A run still out
|
|
150
188
|
for them is called off by `actionRunEffect` (so by a route action) and carries
|
package/docs/data_states.md
CHANGED
|
@@ -90,6 +90,14 @@ puts a reload on the second line as well, and so does
|
|
|
90
90
|
[`keepPageOnScreen`](./resource.md#keeppageonscreen-the-page-on-screen-drawn-again-by-the-next-document) for
|
|
91
91
|
what the page on screen reads — a `GET_MANY` and a `GET_RANGE` included.
|
|
92
92
|
|
|
93
|
+
**Params moving ask another question, and its first answer is a first load.** A
|
|
94
|
+
binding following a signal lands on an instance with no answer, on the first
|
|
95
|
+
line: an action made with `createAction`, or the `GET` of a relation, which does
|
|
96
|
+
not look in the store. What declares that the previous answer stands in starts on
|
|
97
|
+
the second line: a `GET_MANY`, or `createAction(callback, { inheritData: true })`
|
|
98
|
+
([actions.md](./actions.md#while-the-next-answer-comes),
|
|
99
|
+
[resource.md](./resource.md#what-a-read-shows-while-its-params-move)).
|
|
100
|
+
|
|
93
101
|
**The emptiness test is `data === undefined`, never `loading`.** Reading
|
|
94
102
|
`loading` as "there is nothing to display" blanks the screen on every refresh —
|
|
95
103
|
for a checkbox ticked on one row of a list, the whole list goes. A list is no
|
package/docs/drag_to_travel.md
CHANGED
|
@@ -38,12 +38,21 @@ the pointer inside a box that travels.
|
|
|
38
38
|
pointer it has already cancelled (see
|
|
39
39
|
[mobile_touch.md](./mobile_touch.md#the-browser-decides-about-8px-in-and-does-not-wait)).
|
|
40
40
|
Its price is the click of a tap that shook more than 6px.
|
|
41
|
-
- **A
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
picture
|
|
41
|
+
- **A page change is asked for a little later than the press is taken.** A
|
|
42
|
+
`RouteTravel` holds the press at the same 6px, but nothing is asked of the
|
|
43
|
+
router until the hand has pulled 10px further, 16px in all with a finger: a
|
|
44
|
+
navigation, a render and the requests of the page arriving are not worth a
|
|
45
|
+
hand that only shook. Turned around before that, it simply picks the other
|
|
46
|
+
neighbour. The picture sets off from where it stands rather than jumping those
|
|
47
|
+
pixels, and let go of before that, nothing has moved.
|
|
48
|
+
- **Letting go asks where the hand is about to put things.** Where the picture
|
|
49
|
+
stands, plus half a second at the speed the fingertip has as it lifts, against
|
|
50
|
+
half the box. A flick lands far and goes. A hand thrown back lands short and
|
|
51
|
+
everything goes back, otherwise a screen caught in flight and thrown back
|
|
52
|
+
still arrives. A hand that slowed to a stop has no speed left, and the picture
|
|
53
|
+
answers alone. Speed counts from 25px of finger, a tap that slipped not being
|
|
54
|
+
a flick, and past 0.4 px/ms it answers on its own, or half a wide box would be
|
|
55
|
+
out of reach of any flick.
|
|
47
56
|
- Pulling towards nothing follows the finger at a fraction of its distance and
|
|
48
57
|
comes back: a wall one can lean on, never walk through.
|
|
49
58
|
- **A direction that will be refused is one of those walls, and it must be a
|
|
@@ -210,6 +219,7 @@ carry screens.
|
|
|
210
219
|
| what the screens are | `<Slide>`s in one box, all mounted | routes — one mounted, ever |
|
|
211
220
|
| what says which is here | a `signal`, `current` / a command | the URL |
|
|
212
221
|
| what the finger moves | a translated track | the pictures of a view transition |
|
|
222
|
+
| when the picture moves | from the press becoming a gesture | from 10px after that |
|
|
213
223
|
| letting go too early | the track comes back | the transition is played backwards |
|
|
214
224
|
| what says the order | the layout map | the `<Route>` children, in order |
|
|
215
225
|
| what one wheel push is | `move(±1)`, as an arrow key | one travel, as a tab pressed |
|
package/docs/navigation.md
CHANGED
|
@@ -554,6 +554,23 @@ replace moves the scroll
|
|
|
554
554
|
([below](#a-row-of-tabs-where-a-replace-is-an-arrival)). Several `RouteTravel`
|
|
555
555
|
boxes may live on one page, and only the one travelling is captured.
|
|
556
556
|
|
|
557
|
+
**The URL says where the hand is heading, not where the reader is.** It changes
|
|
558
|
+
once the hand has really pulled, and comes back if the page is let go of. So a
|
|
559
|
+
counter, a title or a breadcrumb around the box reads
|
|
560
|
+
`routeTravelSettledPageSignal` first, or it moves for a pull that goes nowhere:
|
|
561
|
+
|
|
562
|
+
```jsx
|
|
563
|
+
const settledPage = routeTravelSettledPageSignal.value;
|
|
564
|
+
const shownId = settledPage ? settledPage.params.gameId : currentId;
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
It holds the `{ route, params }` the travel set off from for as long as the
|
|
568
|
+
pictures move, and is `null` when they stop, the URL being the truth again. A
|
|
569
|
+
page walked whole under the hand has arrived. A tab pressed or a wheel pushed
|
|
570
|
+
holds nothing, and `null` is all they ever read. One signal for the document, as
|
|
571
|
+
there is one transition at a time: on a page with several boxes, `route` says
|
|
572
|
+
which row is travelling.
|
|
573
|
+
|
|
557
574
|
`RouteTravel` is for pages that form a ROW the finger can push; pages related
|
|
558
575
|
pair by pair are animated with `defineRouteTransition`, and a given pair by one
|
|
559
576
|
of the two, never both (see
|
package/docs/resource.md
CHANGED
|
@@ -42,6 +42,7 @@ Actions are read in components through the action system (`useAsyncData`,
|
|
|
42
42
|
- [Callback return contracts](#callback-return-contracts)
|
|
43
43
|
- [When the backend answers a sub-route with the whole parent](#when-the-backend-answers-a-sub-route-with-the-whole-parent)
|
|
44
44
|
- [Relations and autorerun](#relations-and-autorerun)
|
|
45
|
+
- [What a read shows while its params move](#what-a-read-shows-while-its-params-move)
|
|
45
46
|
- [`withParams()`: a scope with reruns of its own](#withparams-a-scope-with-reruns-of-its-own)
|
|
46
47
|
- [`dependencies`: rerun after another resource writes](#dependencies-rerun-after-another-resource-writes)
|
|
47
48
|
- [A function calling the verb, or the instance](#a-function-calling-the-verb-or-the-instance)
|
|
@@ -666,6 +667,43 @@ is a resource of its own, refreshed only by these rules. When a parent field
|
|
|
666
667
|
depends on a child mutation, say so with `dependencies` rather than relying on a
|
|
667
668
|
rerun that will not happen.
|
|
668
669
|
|
|
670
|
+
## What a read shows while its params move
|
|
671
|
+
|
|
672
|
+
A binding following a signal — a route action, `bindParams(signal)` — moves to
|
|
673
|
+
another instance when its params change, and that instance has no answer yet.
|
|
674
|
+
What it holds until its answer lands depends on the action
|
|
675
|
+
([actions.md](./actions.md#while-the-next-answer-comes)):
|
|
676
|
+
|
|
677
|
+
| Action | Until its answer lands |
|
|
678
|
+
| -------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
|
|
679
|
+
| `GET` | the row the store holds for these params, or nothing |
|
|
680
|
+
| the `GET` of a relation (`.one()`, `.scopedOne()`, one item of `.many()` or `.scopedMany()`) | nothing, whatever the store holds |
|
|
681
|
+
| `GET_MANY`, and the `GET_MANY` of `.many()` or `.scopedMany()` | the previous list |
|
|
682
|
+
| a write (`POST`, `PUT`, `PATCH`, `DELETE`, plural or not) | what the previous instance held |
|
|
683
|
+
|
|
684
|
+
A read of one item never starts on the previous answer: it would be another row,
|
|
685
|
+
or another owner's, drawn under the new params, and nothing would give it away.
|
|
686
|
+
|
|
687
|
+
A list hands over because one standing in for the next beats a skeleton. That is
|
|
688
|
+
right for a search, the same collection asked again, and for a list nobody reads
|
|
689
|
+
as a claim about its owner: a sheet of courts that catches up with the club a
|
|
690
|
+
round trip later. It is false where the list says something about who it belongs
|
|
691
|
+
to: one person's partners, on another's profile. The read cannot tell the two
|
|
692
|
+
apart and the screen can, so the screen says it on its binding:
|
|
693
|
+
|
|
694
|
+
```js
|
|
695
|
+
const PARTNERS_ACTION = routeAction(
|
|
696
|
+
PROFILE_ROUTE,
|
|
697
|
+
USER_PARTNERS.GET_MANY,
|
|
698
|
+
() => ({ id: profileIdSignal.value }),
|
|
699
|
+
{ inheritData: false },
|
|
700
|
+
);
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
A `GET_RANGE` reader has no such choice to make: bound to other params it is
|
|
704
|
+
another collection, drawn from its first item
|
|
705
|
+
([above](#a-question-that-follows-a-search-field)).
|
|
706
|
+
|
|
669
707
|
## `withParams()`: a scope with reruns of its own
|
|
670
708
|
|
|
671
709
|
A resource reruns its own reads after its own writes (`rerunOn`, see
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/navi",
|
|
3
|
-
"version": "0.29.
|
|
3
|
+
"version": "0.29.523",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Library of components including navigation to create frontend applications",
|
|
6
6
|
"repository": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"preact": "^11.0.0-rc.2"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@jsenv/dom": "0.17.
|
|
37
|
+
"@jsenv/dom": "0.17.102",
|
|
38
38
|
"@jsenv/humanize": "1.8.11",
|
|
39
39
|
"@jsenv/validity": "0.4.7"
|
|
40
40
|
},
|