@jsenv/navi 0.29.232 → 0.29.234

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.
@@ -43,8 +43,10 @@ form sits in decides: a popup closes, a slide goes on, a form on a page does
43
43
  nothing.
44
44
 
45
45
  `--navi-reset` is the one to reach for when the form is a place one comes back
46
- to — an entry created, then the next one — since the fields go back to their
47
- `defaultValue` and the form is measured against that again:
46
+ to — an entry created, then the next one: the fields go back to their
47
+ `defaultValue`, ready for the next entry. (What the form is measured against
48
+ stays what was just sent — see below — so the emptied form reads as changed,
49
+ and the fields' own constraints are what keep an empty one from being sent.)
48
50
 
49
51
  ```jsx
50
52
  <Form action={createPlaceGroup} command="--navi-reset">
package/docs/i18n.md CHANGED
@@ -143,8 +143,8 @@ preferring German resolves to German, and every key missing in German falls back
143
143
  to its key. With it, that browser lands on the app's best available language
144
144
  instead.
145
145
 
146
- It decides more than the wording: `<Time>`, `<Number>` and every format helper
147
- read the same signal, so **a document that never calls it follows the browser,
146
+ It decides more than the wording: `<Time>` and the format helpers
147
+ (`formatNumber`, `formatTime`, …) read the same signal, so **a document that never calls it follows the browser,
148
148
  dates and numbers included** — `2026-09-01` reads "09/01/2026" on an en-US
149
149
  machine and "01/09/2026" on a French one, from the same code and the same data.
150
150
  Nothing on screen says which reading is being applied, so this is worth one call
@@ -99,10 +99,12 @@ moved by changing this one line.
99
99
 
100
100
  Two things about it:
101
101
 
102
- - **it belongs in the routes module, above the `route()` calls it governs** —
103
- those read the base url as they are created. In the entry point it would be
104
- too late: the import of the routes module runs first, and an import sorter
105
- would put it there anyway;
102
+ - **it belongs in the routes module, above `setupRoutes()`** — the base url
103
+ is read whenever an address is matched or built, and the first match happens
104
+ right there, as the routes are set up against the current address. In the
105
+ entry point it would be too late: the import of the routes module runs
106
+ first, `setupRoutes()` with it, and an import sorter would put the call after
107
+ anyway;
106
108
  - **the server has to answer the document for every address below it.** jsenv's
107
109
  dev server already does: an address it finds no file for is answered with the
108
110
  closest html file above it, `<dirname>.html` included, so `/admin/places/42`
@@ -341,17 +343,35 @@ a route action, and the redirection once the answer is there.
341
343
 
342
344
  ```js
343
345
  export const ADMIN_ROUTE = route("/admin");
344
-
345
- routeAction(ADMIN_ROUTE, async () => {
346
- const me = await ME.GET.run();
347
- firstSectionAllowed(me).redirectTo();
348
- });
346
+ const anySectionMatchingSignal = anyMatchingRouteSignal([
347
+ PLACES_ROUTE,
348
+ USERS_ROUTE,
349
+ ]);
350
+
351
+ routeAction(
352
+ ADMIN_ROUTE,
353
+ async () => {
354
+ const me = await ME.GET.run();
355
+ firstSectionAllowed(me).redirectTo();
356
+ },
357
+ // only on the landing itself: "/admin" also matches every section below it
358
+ () => !anySectionMatchingSignal.value,
359
+ );
349
360
  ```
350
361
 
351
362
  `redirectTo()` replaces the entry rather than stacking onto it, so the back
352
363
  button still leaves by where the reader came in — the one property of a
353
364
  redirection worth keeping here.
354
365
 
366
+ The params are not optional here, for two reasons. A container address matches
367
+ everything below it, so without the gate the landing would fire on every
368
+ section and send the reader back to the first one. And a route action declared
369
+ without params is fetched ahead of the arrival — a link to it preruns it when
370
+ the pointer reaches the link (see [dynamic_import.md](./dynamic_import.md)),
371
+ which for a read is a head start and for a navigation is the navigation
372
+ happening on a hover. Params say the action asks something of the address, and
373
+ that is what keeps it from being prerun.
374
+
355
375
  What it costs, and there is no way around it: the address exists, and something
356
376
  is on screen while the request is out. That is honest — the reader IS waiting —
357
377
  so give `/admin` the screen a wait deserves (the section frame, a `<Loading>`)
package/docs/resource.md CHANGED
@@ -514,9 +514,10 @@ two affordances for the same delete that must both go busy at once. Nothing else
514
514
  in the stack answers that question: the store holds the data, not who is
515
515
  currently writing it.
516
516
 
517
- Either way, what to READ afterwards is the store, or the instance that ran — a
518
- verb keeps no state of its own, so `GAME_CANDIDATES.POST.dataSignal` is empty
519
- whichever form ran it (see
517
+ Either way, what to READ afterwards is the store, or the instance that ran —
518
+ never the verb: a run made with params lands on the child those params made,
519
+ so `GAME_CANDIDATES.POST.dataSignal` is empty whichever form ran it. The verb's
520
+ own signals hold only a run made on the verb itself, with no params (see
520
521
  [actions.md](./actions.md#the-answer-is-kept-on-the-instance-that-ran)).
521
522
 
522
523
  Where it does not pay, and most call sites are here: one affordance, in one
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/navi",
3
- "version": "0.29.232",
3
+ "version": "0.29.234",
4
4
  "type": "module",
5
5
  "description": "Library of components including navigation to create frontend applications",
6
6
  "repository": {