@loadbare/app 0.18.2 → 0.19.1
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/README.md +17 -17
- package/dist/build/assemble.d.ts +7 -1
- package/dist/build/assemble.d.ts.map +1 -1
- package/dist/build/assemble.js +81 -11
- package/dist/build/assemble.js.map +1 -1
- package/dist/build/cli.d.ts +3 -0
- package/dist/build/cli.d.ts.map +1 -1
- package/dist/build/cli.js +6 -1
- package/dist/build/cli.js.map +1 -1
- package/dist/build/declared.d.ts +25 -0
- package/dist/build/declared.d.ts.map +1 -0
- package/dist/build/declared.js +62 -0
- package/dist/build/declared.js.map +1 -0
- package/dist/build/pages.d.ts +6 -0
- package/dist/build/pages.d.ts.map +1 -1
- package/dist/build/pages.js +32 -12
- package/dist/build/pages.js.map +1 -1
- package/docs/comparison.md +697 -484
- package/docs/departures.md +63 -0
- package/docs/miswarts.md +140 -0
- package/docs/opinions.md +155 -0
- package/docs/reference/builder.md +20 -4
- package/docs/reference/chrome.md +45 -10
- package/docs/reference/css.md +0 -1
- package/docs/reference/custom-elements.md +3 -25
- package/docs/reference/data-binding.md +265 -48
- package/docs/reference/names.md +250 -0
- package/docs/reference/overview.md +6 -0
- package/docs/reference/page-files.md +77 -9
- package/docs/reference/server.md +54 -1
- package/docs/roadmap.md +55 -43
- package/docs/testing.md +62 -28
- package/docs/theory.md +348 -108
- package/docs/tutorials/040-displaying-data.md +1 -1
- package/package.json +1 -1
- package/skills/loadbare-app/SKILL.md +19 -13
- package/skills/loadbare-app/references/builder.md +20 -4
- package/skills/loadbare-app/references/chrome.md +45 -10
- package/skills/loadbare-app/references/css.md +0 -1
- package/skills/loadbare-app/references/custom-elements.md +3 -25
- package/skills/loadbare-app/references/data-binding.md +265 -48
- package/skills/loadbare-app/references/miswarts.md +140 -0
- package/skills/loadbare-app/references/names.md +250 -0
- package/skills/loadbare-app/references/overview.md +6 -0
- package/skills/loadbare-app/references/page-files.md +77 -9
- package/skills/loadbare-app/references/server.md +54 -1
- package/docs/TECHREF-1.0.md +0 -2312
- package/docs/possible-ideas.md +0 -314
- package/docs/theory-old.md +0 -839
- package/docs/what-does-loadbare-extend.md +0 -124
- package/skills/loadbare-app/references/TECHREF-1.0.md +0 -2312
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A page shows server data by naming queries and columns in its HTML, and asks
|
|
4
4
|
the server to change that data by naming requests. The developer writes
|
|
5
|
-
|
|
5
|
+
sixteen `lb-` attributes. The server declares every query a page may show and
|
|
6
6
|
every request it may send, and refuses anything it has not declared.
|
|
7
7
|
|
|
8
8
|
Everything is a query. A query is a name for rows, of kind `row` or `rows`,
|
|
@@ -48,6 +48,10 @@ each with its key, and permits the three requests on `roster`; see
|
|
|
48
48
|
| `lb-show` | Any element but `<template>` | The column that decides whether it is present |
|
|
49
49
|
| `lb-order` | An element with `lb-query` | The choice holding the user's order; see [Order](#order) |
|
|
50
50
|
| `lb-filter` | An element with `lb-query` | The columns a choice filters; see [Filters](#filters) |
|
|
51
|
+
| `lb-group` | A `<template>` | Nothing: it marks a group template; see [Groups](#groups) |
|
|
52
|
+
| `lb-count` | Any element | Nothing: it shows a count of rows; see [Aggregates](#aggregates) |
|
|
53
|
+
| `lb-sum`, `lb-avg`, `lb-min`, `lb-max` | Any element | The column aggregated; see [Aggregates](#aggregates) |
|
|
54
|
+
| `lb-select` | A checkbox in a row template | Nothing: it selects its live row; see [Selecting rows](#selecting-rows) |
|
|
51
55
|
| `lb-request` | Any element | The request it sends when it commits |
|
|
52
56
|
| `lb-url-link` | An `<a>` | A link between pages; see [chrome](./chrome.md#links) |
|
|
53
57
|
| `lb-url-push` | An element with `lb-request` | A URL change that pushes a history entry |
|
|
@@ -62,8 +66,14 @@ builder writes a stamp, and a stylesheet or a custom element reads it.
|
|
|
62
66
|
| `lb-key-value` | The key of a live row, or of a `row` landed on an element |
|
|
63
67
|
| `lb-row-live` | The element is a live row |
|
|
64
68
|
| `lb-query-row-count` | The number of live rows an element shows |
|
|
69
|
+
| `lb-group-live`, `lb-group-column`, `lb-group-value` | A group, the column it breaks on, and its value; see [Groups](#groups) |
|
|
70
|
+
| `lb-row-created`, `lb-row-changed`, `lb-row-moved`, `lb-row-requested` | What happened to a row; see [What happened to a row](#what-happened-to-a-row) |
|
|
71
|
+
| `lb-row-leaving`, `lb-group-leaving` | A row or group on its way out |
|
|
72
|
+
| `lb-row-editing` | The row a form is pointed at; see [Editing a row in one form](#editing-a-row-in-one-form) |
|
|
73
|
+
| `lb-row-selected` | A row whose `lb-select` is ticked |
|
|
65
74
|
| `lb-request-pending` | The element's request is in flight |
|
|
66
75
|
| `lb-request-error` | The element's last request failed |
|
|
76
|
+
| `lb-request-refused` | The handler refused it; see [Refusals](#refusals) |
|
|
67
77
|
| `lb-page` | The stub of a page, on its `<template>` |
|
|
68
78
|
| `lb-page-title` | The text of a page file's `<title>` |
|
|
69
79
|
|
|
@@ -79,7 +89,8 @@ elements as the page needs.
|
|
|
79
89
|
|
|
80
90
|
What lands depends on the query's kind and on whether the element holds a
|
|
81
91
|
row template, which is the first `<template>` among its descendants outside
|
|
82
|
-
any nested `lb-query
|
|
92
|
+
any nested `lb-query`, or, when that template is a [group
|
|
93
|
+
template](#groups), the innermost template inside it:
|
|
83
94
|
|
|
84
95
|
| Kind | Row template | The hub |
|
|
85
96
|
|--------|--------------|----------------------------------------|
|
|
@@ -118,6 +129,9 @@ row's `account`:
|
|
|
118
129
|
`lb-column` on an element with `lb-query` is undefined unless the element is
|
|
119
130
|
a control.
|
|
120
131
|
|
|
132
|
+
A query that arrives with nowhere to land is reported to the console,
|
|
133
|
+
unless its name begins with `lb-`.
|
|
134
|
+
|
|
121
135
|
An element with `lb-column` and no ancestor row receives nothing. The hub
|
|
122
136
|
still gathers from it, so an insert form writes `lb-column` on controls that
|
|
123
137
|
no row fills.
|
|
@@ -140,7 +154,9 @@ element that is not a control keeps the content the builder placed in it
|
|
|
140
154
|
from its element file, and renders `lb-column-value` itself; see
|
|
141
155
|
[Custom Elements](./custom-elements.md#receiving-a-value).
|
|
142
156
|
|
|
143
|
-
A file input receives nothing,
|
|
157
|
+
A file input receives nothing, not even `lb-column-value`, and the hub
|
|
158
|
+
reports it to the console and gathers nothing from it. A `<select>` with no
|
|
159
|
+
option for the value shows no selection.
|
|
144
160
|
|
|
145
161
|
The hub hands every value to the browser as the server sent it. What a
|
|
146
162
|
number, a date or a null looks like is decided in the query, or by a custom
|
|
@@ -151,7 +167,8 @@ column the user sorts or filters raw, and format it in the element.
|
|
|
151
167
|
### Checkboxes
|
|
152
168
|
|
|
153
169
|
A checkbox is a control. It is checked when its column is anything but
|
|
154
|
-
`false` or null, and it sends `"true"` or `"false"
|
|
170
|
+
`false` or null, and it sends `"true"` or `"false"`
|
|
171
|
+
([miswart](./miswarts.md#checkboxes-and-radio-groups-always-gather-a-value)):
|
|
155
172
|
|
|
156
173
|
```html
|
|
157
174
|
<input type="checkbox" lb-column="active" lb-request="lb-row-update" />
|
|
@@ -176,8 +193,9 @@ when none is:
|
|
|
176
193
|
|
|
177
194
|
In a row template, the hub stamps each radio button's `name` with the
|
|
178
195
|
`name` written, or its column when none is, followed by `-` and the live
|
|
179
|
-
row's key, so each live row holds a group of its own
|
|
180
|
-
|
|
196
|
+
row's key, so each live row holds a group of its own
|
|
197
|
+
([miswart](./miswarts.md#radio-button-names-in-a-row-template)). Rows not yet
|
|
198
|
+
entered share the empty key, and so share one group.
|
|
181
199
|
|
|
182
200
|
A radio button in a query's row template answers to that query's row, as
|
|
183
201
|
any element there does. A choice among a query's rows is better made with
|
|
@@ -209,7 +227,11 @@ what was typed, through a refresh and through a change of order. A row
|
|
|
209
227
|
whose values changed is filled whole, and its controls show what arrived.
|
|
210
228
|
|
|
211
229
|
A key is unique within a query. Two rows with one key in the same answer,
|
|
212
|
-
or two live rows showing one key, are reported on the console.
|
|
230
|
+
or two live rows showing one key, are reported on the console. A row
|
|
231
|
+
missing its key column is reported and not landed.
|
|
232
|
+
|
|
233
|
+
A live row already in the markup when the first answer lands is one of the
|
|
234
|
+
query's rows.
|
|
213
235
|
|
|
214
236
|
When the focus is in a live row that placing moves, the hub puts it back on
|
|
215
237
|
the same element and scrolls it into view. When that row leaves, or a
|
|
@@ -254,14 +276,23 @@ server's order places the rows:
|
|
|
254
276
|
</ul>
|
|
255
277
|
```
|
|
256
278
|
|
|
257
|
-
Values
|
|
258
|
-
|
|
259
|
-
|
|
279
|
+
| Values | Compare |
|
|
280
|
+
|----------------------|----------------------------------------------|
|
|
281
|
+
| Two numbers | Numerically |
|
|
282
|
+
| Two strings | As the user's language orders them |
|
|
283
|
+
| Two booleans | `false` before `true` |
|
|
284
|
+
| Two different types | Booleans, then numbers, then strings |
|
|
285
|
+
| `null` or missing | After everything ascending, first descending |
|
|
286
|
+
|
|
287
|
+
A number sent as a string sorts as a string, unless the query declares the
|
|
260
288
|
column's [type](./page-files.md#queries): a column declared `number` sorts
|
|
261
289
|
numerically whatever JSON type its values arrive as, and a value that is no
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
290
|
+
value of its declared type compares as `null` does. `readAs` in
|
|
291
|
+
`@loadbare/app/types` is the rule the hub applies.
|
|
292
|
+
|
|
293
|
+
Rows that compare equal keep the order they arrived in, a patch's new rows
|
|
294
|
+
after the rows already showing. A row moves only when the order
|
|
295
|
+
puts it somewhere else, so all rows landing again unchanged move nothing.
|
|
265
296
|
|
|
266
297
|
### Filters
|
|
267
298
|
|
|
@@ -280,7 +311,8 @@ its rows the user may filter, separated by commas. The column of
|
|
|
280
311
|
```
|
|
281
312
|
|
|
282
313
|
A row that does not pass every filter is `hidden`, and a ticked `lb-select`
|
|
283
|
-
in it is cleared. A group whose rows are all hidden is hidden too
|
|
314
|
+
in it is cleared. A group whose rows are all hidden is hidden too
|
|
315
|
+
([miswart](./miswarts.md#rows-hidden-by-a-filter)). An empty
|
|
284
316
|
choice filters nothing.
|
|
285
317
|
|
|
286
318
|
A filter is one or more terms, each an operator followed by a value:
|
|
@@ -310,6 +342,9 @@ The column's type is the one its query declares, if it declares one, and
|
|
|
310
342
|
its JSON type otherwise. A value that is not of the column's type, and a
|
|
311
343
|
column that is null or missing, pass only `!=`.
|
|
312
344
|
|
|
345
|
+
`parseFilter`, `passes` and `passesTerm` in `@loadbare/app/types` are the
|
|
346
|
+
rule the hub applies.
|
|
347
|
+
|
|
313
348
|
### Groups
|
|
314
349
|
|
|
315
350
|
A group is a run of rows sharing the order's leading term. Write a
|
|
@@ -330,11 +365,32 @@ template. The nth group template breaks on the order's nth term.
|
|
|
330
365
|
</ul>
|
|
331
366
|
```
|
|
332
367
|
|
|
333
|
-
The group
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
nested template is
|
|
368
|
+
The hub clones the group template where the order breaks, and the group's
|
|
369
|
+
contents land immediately before the clone of its nested template, so the
|
|
370
|
+
markup's nesting decides the shape:
|
|
371
|
+
|
|
372
|
+
| The nested template is | The group's contents land | Example |
|
|
373
|
+
|------------------------------|------------------------------------|-----------------------------------|
|
|
374
|
+
| Inside the heading's element | Inside it | `<tbody>`, `<li>`, `<details>` |
|
|
375
|
+
| Beside the heading | After the heading, as its siblings | A heading `<tr>` in one `<tbody>` |
|
|
376
|
+
|
|
377
|
+
`<tbody>` and `<optgroup>` do not nest, so a table's levels below the first
|
|
378
|
+
are heading rows beside their rows:
|
|
379
|
+
|
|
380
|
+
```html
|
|
381
|
+
<table lb-query="accounts">
|
|
382
|
+
<thead><tr><th>Account</th></tr></thead>
|
|
383
|
+
<template lb-group>
|
|
384
|
+
<tbody>
|
|
385
|
+
<tr><th scope="rowgroup" lb-column="category"></th></tr>
|
|
386
|
+
<template><tr><td lb-column="account_name"></td></tr></template>
|
|
387
|
+
</tbody>
|
|
388
|
+
</template>
|
|
389
|
+
</table>
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
Content after the nested template lands after the group's rows, which is
|
|
393
|
+
where a group's footer goes.
|
|
338
394
|
|
|
339
395
|
A heading is filled from its group's first row, so it may show a column
|
|
340
396
|
other than the one the group breaks on. The hub stamps each top-level
|
|
@@ -343,6 +399,10 @@ element of a group with `lb-group-live`, `lb-group-column` and
|
|
|
343
399
|
row. When the order changes, a group whose run goes on is kept and moved,
|
|
344
400
|
and a group whose run ended leaves.
|
|
345
401
|
|
|
402
|
+
A group template with no nested template is reported to the console. More
|
|
403
|
+
group templates than the order has terms show each extra level as one
|
|
404
|
+
group, and are reported once.
|
|
405
|
+
|
|
346
406
|
### Aggregates
|
|
347
407
|
|
|
348
408
|
`lb-count`, `lb-sum="col"`, `lb-avg="col"`, `lb-min="col"` and
|
|
@@ -353,10 +413,24 @@ or of the whole list outside any group:
|
|
|
353
413
|
<tr><td><span lb-count></span> people</td><td lb-sum="salary"></td></tr>
|
|
354
414
|
```
|
|
355
415
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
416
|
+
| Attribute | Sets the element to |
|
|
417
|
+
|----------------|-----------------------------------------------------------|
|
|
418
|
+
| `lb-count` | The number of rows |
|
|
419
|
+
| `lb-sum="col"` | The sum of `col` |
|
|
420
|
+
| `lb-avg="col"` | The average of `col` |
|
|
421
|
+
| `lb-min="col"` | The least value of `col`, by the [order](#order)'s comparison |
|
|
422
|
+
| `lb-max="col"` | The greatest, likewise |
|
|
423
|
+
|
|
424
|
+
An aggregate lands as a column does, with `lb-column-value`. A sum and an
|
|
425
|
+
average are exact decimals, read from JSON numbers and from strings holding
|
|
426
|
+
a plain decimal, as Postgres sends `numeric`. A sum has as many places as
|
|
427
|
+
the most precise value, and an average up to two more. `null` and empty
|
|
428
|
+
values are left out, as SQL leaves them out, and any other value is left
|
|
429
|
+
out and reported once. The result lands unformatted.
|
|
430
|
+
|
|
431
|
+
An aggregate covers the rows showing, so a row a filter hides is left out.
|
|
432
|
+
Where the true total matters beyond what the page shows, have the server
|
|
433
|
+
answer it as a row.
|
|
360
434
|
|
|
361
435
|
### What happened to a row
|
|
362
436
|
|
|
@@ -371,9 +445,16 @@ Every change to a list is one a stylesheet can see:
|
|
|
371
445
|
| `lb-row-leaving` | A row on its way out |
|
|
372
446
|
| `lb-group-leaving` | A group on its way out |
|
|
373
447
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
448
|
+
The hub touches a row when an answer names it. `lb-row-created`,
|
|
449
|
+
`lb-row-changed` and `lb-row-moved` are cleared when it next does, and one
|
|
450
|
+
applied again is removed and added as two changes, so an animation keyed to
|
|
451
|
+
it plays again. `lb-row-requested` is cleared at every landing of the row's
|
|
452
|
+
query, and set only by a landing that answers a request from the page.
|
|
453
|
+
|
|
454
|
+
A row or a group that leaves loses `lb-row-live` or `lb-group-live`, takes
|
|
455
|
+
`lb-row-leaving` or `lb-group-leaving` and `inert`
|
|
456
|
+
([miswart](./miswarts.md#leaving-rows-are-inert)), and is removed once its
|
|
457
|
+
animations finish, at once when there are none.
|
|
377
458
|
|
|
378
459
|
A row is moved when its values changed and the rows whose values did not
|
|
379
460
|
change now stand around it differently. A row it passed is not stamped,
|
|
@@ -384,6 +465,11 @@ and a change of the user's order, which changes no values, stamps none.
|
|
|
384
465
|
[lb-row-leaving] { animation: depart 200ms forwards; }
|
|
385
466
|
```
|
|
386
467
|
|
|
468
|
+
A row never travels between its two places, since that takes measuring, and
|
|
469
|
+
measuring takes script. Scrolling to a row is script too: a custom element
|
|
470
|
+
reads `lb-row-requested` in
|
|
471
|
+
[`lbRowsLanded`](./custom-elements.md#holding-rows).
|
|
472
|
+
|
|
387
473
|
### What arrives later
|
|
388
474
|
|
|
389
475
|
The hub keeps each query's last answer until the page changes, with any
|
|
@@ -437,6 +523,39 @@ hides is not counted. An empty query is a stylesheet rule:
|
|
|
437
523
|
The element carrying `lb-query` is a `<div>` here rather than the `<ul>`, so
|
|
438
524
|
that the message is inside it and one rule reaches both.
|
|
439
525
|
|
|
526
|
+
### Master-detail
|
|
527
|
+
|
|
528
|
+
A master is a `row` query and its detail is a `rows` query, as two names
|
|
529
|
+
answered side by side. A column never holds rows.
|
|
530
|
+
|
|
531
|
+
```html
|
|
532
|
+
<section lb-query="invoice">
|
|
533
|
+
<h2 lb-column="number"></h2>
|
|
534
|
+
<span lb-column="customer"></span>
|
|
535
|
+
</section>
|
|
536
|
+
|
|
537
|
+
<table>
|
|
538
|
+
<tbody lb-query="invoiceLines">
|
|
539
|
+
<template><tr><td lb-column="item"></td><td lb-column="amount"></td></tr></template>
|
|
540
|
+
</tbody>
|
|
541
|
+
</table>
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
Many masters, each with its own detail, is one `rows` query of joined rows:
|
|
545
|
+
each detail row carries its master's columns. A [group template](#groups)
|
|
546
|
+
shows each master as a group, ordered by the master's key first.
|
|
547
|
+
|
|
548
|
+
A query nested in another query's row template receives the same rows in
|
|
549
|
+
every live row. That serves a picker offering the same choices on every
|
|
550
|
+
row, and is not a way to show a different detail per row; see
|
|
551
|
+
[What arrives later](#what-arrives-later).
|
|
552
|
+
|
|
553
|
+
Which master a page shows is a query parm, which a query reads off `ctx`,
|
|
554
|
+
since a query takes no argument from the browser; see
|
|
555
|
+
[Query parms](./chrome.md#query-parms). When a write creates or removes the
|
|
556
|
+
master, the handler moves the URL; see
|
|
557
|
+
[Moving the URL](./page-files.md#moving-the-url).
|
|
558
|
+
|
|
440
559
|
## Conditional rendering
|
|
441
560
|
|
|
442
561
|
A page holds every element it can show. Write `lb-show` on an element,
|
|
@@ -551,10 +670,14 @@ answers with response items, which land like any others.
|
|
|
551
670
|
| A control | `change` |
|
|
552
671
|
| Any other element | `click` |
|
|
553
672
|
|
|
554
|
-
A click inside an element carrying `lb-request` commits it
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
673
|
+
A click inside an element carrying `lb-request` commits it, as long as the
|
|
674
|
+
element is inside `<lb-hub>` and no interactive content lies between them.
|
|
675
|
+
Interactive content is HTML's: `<a href>`, `<button>`, `<input>` other than
|
|
676
|
+
hidden, `<select>`, `<textarea>`, `<label>`, `<details>`, `<iframe>`,
|
|
677
|
+
`<embed>`, `<audio controls>`, `<video controls>` and `<img usemap>`, plus
|
|
678
|
+
any form-associated custom element. A click on one of them belongs to it: a
|
|
679
|
+
click into an input inside a deletable row focuses the input and deletes
|
|
680
|
+
nothing.
|
|
558
681
|
|
|
559
682
|
A submit button with a form owner commits with its form. On `submit`, the
|
|
560
683
|
hub sends the submitter's `lb-request` when the submitter carries one, and
|
|
@@ -588,7 +711,10 @@ carrying `lb-request`:
|
|
|
588
711
|
|
|
589
712
|
The hub gathers from controls only, and skips a control that belongs to a
|
|
590
713
|
query nested inside the group, except that a form gathers the rows of a
|
|
591
|
-
query nested in its own; see [A form over a set of rows](#a-form-over-a-set-of-rows).
|
|
714
|
+
query nested in its own; see [A form over a set of rows](#a-form-over-a-set-of-rows).
|
|
715
|
+
An element carrying `lb-query` and `lb-column` both, such as a picker,
|
|
716
|
+
belongs to the row around it, and is gathered with it and sends for that
|
|
717
|
+
row's query. A form owner includes a control outside the
|
|
592
718
|
form that names it with the HTML `form` attribute, which is how a table row,
|
|
593
719
|
where a form cannot go, sends one:
|
|
594
720
|
|
|
@@ -660,8 +786,10 @@ query's name, in `rows`:
|
|
|
660
786
|
The list of deduction types lives only in the database: the nested query
|
|
661
787
|
answers it, and the form shows one input per row.
|
|
662
788
|
|
|
663
|
-
- Every live row of the nested query
|
|
664
|
-
empty value means, such as no deduction of that type,
|
|
789
|
+
- Every live row of the nested query that holds a control goes, whatever
|
|
790
|
+
its values. What an empty value means, such as no deduction of that type,
|
|
791
|
+
is the handler's. A picker's options hold no control, so a picker in the
|
|
792
|
+
form sends its own value and none of its rows.
|
|
665
793
|
- One level only. A query nested inside a nested row shows the same rows in
|
|
666
794
|
every row around it, so it is not gathered.
|
|
667
795
|
- An insert, an update and a declared request carry `rows`. A delete does
|
|
@@ -671,7 +799,9 @@ answers it, and the form shows one input per row.
|
|
|
671
799
|
- A live row gathers nothing nested, as before.
|
|
672
800
|
|
|
673
801
|
The handler for the form's query receives `rows` beside `values`, and writes
|
|
674
|
-
the master and its details together; see [crud](./page-files.md#crud).
|
|
802
|
+
the master and its details together; see [crud](./page-files.md#crud). The
|
|
803
|
+
server checks that `rows` holds string keys and string values by query, and
|
|
804
|
+
ignores a request whose `rows` does not.
|
|
675
805
|
|
|
676
806
|
A nested query answers once for the page, so its rows are the same wherever
|
|
677
807
|
they show. The form enters a new master with its details, or edits the
|
|
@@ -708,9 +838,14 @@ holds what a submit will gather:
|
|
|
708
838
|
</section>
|
|
709
839
|
```
|
|
710
840
|
|
|
711
|
-
The same holds for a request a custom element sends carrying `key: ""`.
|
|
712
|
-
|
|
713
|
-
|
|
841
|
+
The same holds for a request a custom element sends carrying `key: ""`. No
|
|
842
|
+
ancestor sees a request not sent, and it gets no `lb-request-done`. An
|
|
843
|
+
update or delete with no row around it at all has no key either, and that
|
|
844
|
+
is reported to the console.
|
|
845
|
+
|
|
846
|
+
A field the request already carries is its issuer's and is kept, so a
|
|
847
|
+
custom element that dispatches its own request with `values` is not
|
|
848
|
+
gathered over.
|
|
714
849
|
|
|
715
850
|
### Inserting, updating and deleting rows
|
|
716
851
|
|
|
@@ -727,6 +862,10 @@ The hub sends one of these only when it has what the table lists, and
|
|
|
727
862
|
otherwise reports to the console. An insert or an update that gathers
|
|
728
863
|
nothing is not sent.
|
|
729
864
|
|
|
865
|
+
For a query the hub serves, `lb-url` or `lb-choices`, the hub answers
|
|
866
|
+
`lb-row-update` itself, with no round trip; see
|
|
867
|
+
[Query parms](./chrome.md#query-parms) and [Choices](#choices).
|
|
868
|
+
|
|
730
869
|
A key comes from a live row, or from an element a `row` landed on, so all
|
|
731
870
|
three work against either kind:
|
|
732
871
|
|
|
@@ -790,11 +929,13 @@ round trip, including columns no element in the table shows. The user
|
|
|
790
929
|
edits a row they can see, so the row is on the page. A row that has to be
|
|
791
930
|
fetched to be edited is another page, with that row as its master.
|
|
792
931
|
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
form
|
|
796
|
-
|
|
797
|
-
|
|
932
|
+
Pointing a form first empties it: every column it names lands as null, and
|
|
933
|
+
the form resets, so each control returns to its default. Edit then lands
|
|
934
|
+
the row on the form, stamps the form with the row's key, so the form's
|
|
935
|
+
request carries it, and stamps the row `lb-row-editing`. New stamps an
|
|
936
|
+
empty key, making the form [a row not yet entered](#a-row-not-yet-entered).
|
|
937
|
+
Both focus the form's first control. The form's state is in its
|
|
938
|
+
`lb-key-value` stamp:
|
|
798
939
|
|
|
799
940
|
| `lb-key-value` | The form is |
|
|
800
941
|
|----------------|-----------------------------|
|
|
@@ -837,6 +978,11 @@ landing again lands nothing on it, and what the user has typed stays.
|
|
|
837
978
|
A button inside a form that carries a command is `type="button"`, or it
|
|
838
979
|
submits the form instead.
|
|
839
980
|
|
|
981
|
+
A command the hub cannot carry out is reported to the console: Edit from
|
|
982
|
+
outside a live row of the form's query, Edit for a key the hub holds no row
|
|
983
|
+
for, and any command aimed at an element that is not a form carrying
|
|
984
|
+
`lb-query`.
|
|
985
|
+
|
|
840
986
|
### Selecting rows
|
|
841
987
|
|
|
842
988
|
A checkbox carrying `lb-select` in a row template selects the live row it
|
|
@@ -913,7 +1059,7 @@ A button carries no value, so a declared request from one sends the values
|
|
|
913
1059
|
of the live row or form it sits in, and the server computes the rest.
|
|
914
1060
|
|
|
915
1061
|
A request name beginning with `lb-` that is not one of the three is refused
|
|
916
|
-
by the builder.
|
|
1062
|
+
by the builder in markup, and by the hub when a script dispatches it.
|
|
917
1063
|
|
|
918
1064
|
### Request state
|
|
919
1065
|
|
|
@@ -927,7 +1073,8 @@ The hub stamps the element that committed:
|
|
|
927
1073
|
|
|
928
1074
|
`lb-request-error` covers a non-2xx response, a network failure and a
|
|
929
1075
|
timeout alike. The hub aborts a round trip after ten seconds, and sets
|
|
930
|
-
`aria-busy="true"` for as long as `lb-request-pending` is present
|
|
1076
|
+
`aria-busy="true"` for as long as `lb-request-pending` is present
|
|
1077
|
+
([miswart](./miswarts.md#busy-elements-carry-aria-busy)).
|
|
931
1078
|
|
|
932
1079
|
The hub ignores a commit on an element carrying `lb-request-pending`, so a
|
|
933
1080
|
pending button is already disabled and a stylesheet only shows it:
|
|
@@ -977,14 +1124,23 @@ submit, as for any invalid control, so the user edits before trying again.
|
|
|
977
1124
|
|
|
978
1125
|
A form-associated custom element takes a column's message when it has
|
|
979
1126
|
`setCustomValidity` and `reportValidity`; see
|
|
980
|
-
[Being a control](./custom-elements.md#being-a-control).
|
|
1127
|
+
[Being a control](./custom-elements.md#being-a-control). A request for
|
|
1128
|
+
several rows takes the whole-request message only. A column the request
|
|
1129
|
+
gathered no control for is reported to the console.
|
|
1130
|
+
|
|
1131
|
+
On the wire a refusal is status 422 with `{ refusal: { message?, columns? } }`;
|
|
1132
|
+
see [The data channel](./server.md#the-data-channel).
|
|
981
1133
|
|
|
982
1134
|
### The request event
|
|
983
1135
|
|
|
984
1136
|
The hub dispatches every request as a bubbling `lb-request` event from the
|
|
985
1137
|
element that committed, with the request as its `detail`, before sending it.
|
|
986
|
-
|
|
987
|
-
|
|
1138
|
+
The hub completes the request on the event's way down, so every ancestor
|
|
1139
|
+
sees it whole on the way up. An ancestor may stop it, and the request is
|
|
1140
|
+
not sent: the event is not cancelable, so an interceptor calls
|
|
1141
|
+
`stopPropagation`, not `preventDefault`. That is how a confirmation wrapper
|
|
1142
|
+
works without the wrapped element knowing about it. A custom element may
|
|
1143
|
+
dispatch the event itself; see
|
|
988
1144
|
[Sending a request](./custom-elements.md#sending-a-request).
|
|
989
1145
|
|
|
990
1146
|
Once the answer has landed, or the round trip has failed, the hub calls
|
|
@@ -993,6 +1149,37 @@ then dispatches a bubbling `lb-request-done` event from the same element.
|
|
|
993
1149
|
Both carry the request and what landed because of it, or the error; see
|
|
994
1150
|
[Hearing how it turned out](./custom-elements.md#hearing-how-it-turned-out).
|
|
995
1151
|
|
|
1152
|
+
### The round trip
|
|
1153
|
+
|
|
1154
|
+
A request the hub sends has ten seconds to come back. Past that the hub
|
|
1155
|
+
aborts it and treats it as a failure, since `fetch` imposes no deadline of
|
|
1156
|
+
its own. An application cannot change the deadline.
|
|
1157
|
+
|
|
1158
|
+
A round trip fails on a server error, on a network failure, or on that
|
|
1159
|
+
deadline, and all three stamp `lb-request-error` on the element that sent
|
|
1160
|
+
the request. A refusal is not a failure.
|
|
1161
|
+
|
|
1162
|
+
After a successful `lb-row-insert` gathered from a form, the hub resets the
|
|
1163
|
+
form, after it lands the response. A failed insert resets nothing, so the
|
|
1164
|
+
entry can be corrected. An `lb-row-update` resets nothing: the row it sent
|
|
1165
|
+
lands back on its controls.
|
|
1166
|
+
|
|
1167
|
+
A reset of any form, whether the hub's, a reset button's or a script's,
|
|
1168
|
+
returns its controls to their defaults, and the hub removes
|
|
1169
|
+
`lb-column-value` from each of them. A cancelled reset keeps both.
|
|
1170
|
+
|
|
1171
|
+
A page load that fails lands nothing and is reported to the console. A load
|
|
1172
|
+
started by a request for `lb-url` stamps the element that sent it, as any
|
|
1173
|
+
request stamps its element.
|
|
1174
|
+
|
|
1175
|
+
A response answers for the URL its request was sent from, path and query
|
|
1176
|
+
string both. One that returns after the URL has moved lands nothing, since
|
|
1177
|
+
it describes what the user is no longer looking at: a request's answer,
|
|
1178
|
+
including any `url()` it carries, and a page load overtaken by a newer one.
|
|
1179
|
+
A write whose answer is dropped this way has still happened. Its
|
|
1180
|
+
`lb-request-done` carries no items and no error, and an insert still resets
|
|
1181
|
+
its form.
|
|
1182
|
+
|
|
996
1183
|
## The URL
|
|
997
1184
|
|
|
998
1185
|
The hub serves one query of its own, `lb-url`: one row holding the path, the
|
|
@@ -1041,8 +1228,18 @@ The developer writes `lb-` attributes in markup, and script never assigns
|
|
|
1041
1228
|
them. The builder checks the markup of the chrome and of every page, after
|
|
1042
1229
|
expansion, and refuses to build:
|
|
1043
1230
|
|
|
1044
|
-
- an `lb-` attribute that is not one of the
|
|
1231
|
+
- an `lb-` attribute that is not one of the sixteen the developer writes;
|
|
1232
|
+
`lb-exp-slot` and `lb-exp-template` are consumed by expansion and never
|
|
1233
|
+
reach the check
|
|
1045
1234
|
- `lb-request` naming an `lb-` request other than the three Loadbare provides
|
|
1235
|
+
- `lb-query` naming a query the page does not declare; every page and the
|
|
1236
|
+
chrome may name `lb-url` and `lb-choices`, and the chrome names no other
|
|
1237
|
+
- `lb-request` naming a request the page does not declare under `handlers`;
|
|
1238
|
+
the chrome sends none
|
|
1239
|
+
- one of the three requests for a query whose `crud` entry does not declare
|
|
1240
|
+
it, or any but `lb-row-update` for `lb-url` or `lb-choices`; the query is
|
|
1241
|
+
a form's own when the form carries `lb-query`, and otherwise the nearest
|
|
1242
|
+
`lb-query` around the element
|
|
1046
1243
|
- `lb-url-link` on anything but an `<a>`
|
|
1047
1244
|
- `lb-url-push` on an element without `lb-request`
|
|
1048
1245
|
- `lb-url-unknown` on anything but a `<dialog>`, or outside `<lb-hub>`
|
|
@@ -1055,3 +1252,23 @@ expansion, and refuses to build:
|
|
|
1055
1252
|
template, or beside `lb-column` or `lb-request`
|
|
1056
1253
|
- a `command` beginning `--lb-` that is not one of the three commands
|
|
1057
1254
|
- one of the three commands with no `commandfor`
|
|
1255
|
+
- `lb-group` on anything but a `<template>`, or on one holding no
|
|
1256
|
+
`<template>` for its contents
|
|
1257
|
+
- an aggregate on a `<template>`, or any but `lb-count` naming no column
|
|
1258
|
+
- a chrome without exactly one `<lb-hub>` and exactly one `<main>`, a
|
|
1259
|
+
`<main>` outside `<lb-hub>`, or a `<main>` holding anything but whitespace
|
|
1260
|
+
- a page carrying an `<lb-hub>` or a `<main>`
|
|
1261
|
+
|
|
1262
|
+
The builder also reads the script of every custom element it ships, other
|
|
1263
|
+
than `<lb-hub>`, and refuses one that declares a method, accessor or field
|
|
1264
|
+
whose name is `lb`, a capital, and anything Loadbare does not call; see
|
|
1265
|
+
[Reserved methods](./names.md#reserved-methods).
|
|
1266
|
+
|
|
1267
|
+
`lb-column` with no ancestor row is allowed: the hub gathers from it.
|
|
1268
|
+
|
|
1269
|
+
Script never assigns an `lb-` attribute, so the markup states every one
|
|
1270
|
+
that exists, and checking the markup is sound.
|
|
1271
|
+
|
|
1272
|
+
To know what each page declares, the builder loads its `.queries.ts` and
|
|
1273
|
+
`.requests.ts` modules, so their import-time code runs during the build, as
|
|
1274
|
+
it does when the server starts.
|