@loadbare/app 0.21.0 → 0.22.0
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 +18 -0
- package/dist/build/assemble.d.ts.map +1 -1
- package/dist/build/assemble.js +8 -3
- package/dist/build/assemble.js.map +1 -1
- package/dist/build/build.d.ts +62 -0
- package/dist/build/build.d.ts.map +1 -0
- package/dist/build/build.js +148 -0
- package/dist/build/build.js.map +1 -0
- package/dist/build/cli.d.ts +6 -1
- package/dist/build/cli.d.ts.map +1 -1
- package/dist/build/cli.js +25 -78
- package/dist/build/cli.js.map +1 -1
- package/dist/build/declared.d.ts.map +1 -1
- package/dist/build/declared.js +3 -0
- package/dist/build/declared.js.map +1 -1
- package/dist/build/skills-cli.d.ts +2 -1
- package/dist/build/skills-cli.d.ts.map +1 -1
- package/dist/build/skills-cli.js +8 -1
- package/dist/build/skills-cli.js.map +1 -1
- package/dist/build/skills.d.ts +2 -0
- package/dist/build/skills.d.ts.map +1 -1
- package/dist/build/skills.js +2 -0
- package/dist/build/skills.js.map +1 -1
- package/dist/core/lb-constants.d.ts +14 -0
- package/dist/core/lb-constants.d.ts.map +1 -1
- package/dist/core/lb-constants.js +25 -0
- package/dist/core/lb-constants.js.map +1 -1
- package/dist/dev/lb-dev.d.ts +128 -0
- package/dist/dev/lb-dev.d.ts.map +1 -0
- package/dist/dev/lb-dev.js +289 -0
- package/dist/dev/lb-dev.js.map +1 -0
- package/dist/hub/lb-hub.browser.d.ts.map +1 -1
- package/dist/hub/lb-hub.browser.js +119 -15
- package/dist/hub/lb-hub.browser.js.map +1 -1
- package/docs/comparison.md +4 -3
- package/docs/reference/builder.md +12 -4
- package/docs/reference/chrome.md +52 -1
- package/docs/reference/data-binding.md +15 -9
- package/docs/reference/dev-server.md +171 -0
- package/docs/reference/names.md +14 -1
- package/docs/reference/overview.md +1 -0
- package/docs/reference/server.md +8 -3
- package/docs/reference/widgets.md +10 -277
- package/docs/testing.md +2 -1
- package/docs/tutorials/000-getting-started.md +1 -1
- package/docs/tutorials/040-displaying-data.md +1 -1
- package/docs/tutorials/090-using-widget-libraries.md +1 -1
- package/package.json +4 -2
- package/skills/loadbare-app/SKILL.md +28 -10
- package/skills/loadbare-app/references/builder.md +12 -4
- package/skills/loadbare-app/references/chrome.md +52 -1
- package/skills/loadbare-app/references/data-binding.md +15 -9
- package/skills/loadbare-app/references/dev-server.md +171 -0
- package/skills/loadbare-app/references/names.md +14 -1
- package/skills/loadbare-app/references/overview.md +1 -0
- package/skills/loadbare-app/references/server.md +8 -3
- package/skills/loadbare-app/references/widgets.md +10 -277
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# The Basic Widget Library
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
`lb-master`, `lb-checkbox`, `lb-number` and `lb-date`. Every one of them is an ordinary custom element, written
|
|
3
|
+
`@loadbare/widgets` is the basic widget set: controls, a table, dialogs, and
|
|
4
|
+
elements that format a value. Every one of them is an ordinary custom element, written
|
|
6
5
|
against the contracts in [Custom Elements](./custom-elements.md#html) for its
|
|
7
6
|
definition and [Custom Elements](./custom-elements.md#code) for its class.
|
|
8
7
|
|
|
@@ -30,282 +29,16 @@ see [Being a control](./custom-elements.md#being-a-control). Each passes a
|
|
|
30
29
|
refusal's message for its column to the native control inside it; see
|
|
31
30
|
[Refusals](./data-binding.md#refusals).
|
|
32
31
|
|
|
33
|
-
##
|
|
32
|
+
## Each widget
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
Each widget's parameters, the attributes it reads, and what a change sends
|
|
35
|
+
are documented once, in the package that ships it: one page per widget,
|
|
36
|
+
which the loadbare-widgets skill carries. Install that skill beside this one:
|
|
37
37
|
|
|
38
|
-
```html
|
|
39
|
-
<lb-input lb-column="name" lb-request="lb-row-update" exp-label="Name"></lb-input>
|
|
40
38
|
```
|
|
41
|
-
|
|
42
|
-
Inside a form, leave `lb-request` off. The form gathers the widget on submit
|
|
43
|
-
like any other control, so a widget that also sent its own request would
|
|
44
|
-
write the same edit twice.
|
|
45
|
-
|
|
46
|
-
| Parameter | Fills |
|
|
47
|
-
|----------------|----------------------------------|
|
|
48
|
-
| `exp-label` | The visible `<label>` text |
|
|
49
|
-
| `exp-type` | The input's `type`, `text` when absent |
|
|
50
|
-
| `exp-readonly` | The input's `readonly` attribute |
|
|
51
|
-
|
|
52
|
-
## `lb-select`
|
|
53
|
-
|
|
54
|
-
Wraps a `<select>` whose `<option>`s the page writes inside the tag:
|
|
55
|
-
|
|
56
|
-
```html
|
|
57
|
-
<lb-select lb-column="team" lb-request="lb-row-update" exp-label="Team">
|
|
58
|
-
<option value="">No team</option>
|
|
59
|
-
<option value="Engines">Engines</option>
|
|
60
|
-
</lb-select>
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
| Parameter | Fills |
|
|
64
|
-
|-------------|----------------------------|
|
|
65
|
-
| `exp-label` | The visible `<label>` text |
|
|
66
|
-
|
|
67
|
-
## `lb-options`
|
|
68
|
-
|
|
69
|
-
A `<select>` whose `<option>`s are the rows of the query it names. The page
|
|
70
|
-
writes the row template inside the widget:
|
|
71
|
-
|
|
72
|
-
```html
|
|
73
|
-
<lb-options lb-query="statuses" lb-column="status" lb-request="lb-row-update" exp-label="Status">
|
|
74
|
-
<template><option lb-column="label"></option></template>
|
|
75
|
-
</lb-options>
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
| Parameter | Fills |
|
|
79
|
-
|-------------|----------------------------|
|
|
80
|
-
| `exp-label` | The visible `<label>` text |
|
|
81
|
-
| `exp-size` | The `<select>`'s `size`, an open list rather than a drop-down |
|
|
82
|
-
|
|
83
|
-
- Each option's `value` is its row's key, the `lb-key-value` the hub stamps
|
|
84
|
-
on the live row, so the widget holds a key and shows a label.
|
|
85
|
-
- A group template holding an `<optgroup>` puts the options in groups, one
|
|
86
|
-
per run of the query's order's leading term. The widget labels each
|
|
87
|
-
`<optgroup>` from the `lb-group-value` the hub stamps on it:
|
|
88
|
-
|
|
89
|
-
```html
|
|
90
|
-
<template lb-group>
|
|
91
|
-
<optgroup><template><option lb-column="label"></option></template></optgroup>
|
|
92
|
-
</template>
|
|
93
|
-
```
|
|
94
|
-
- A heading option marked `data-group-label` in the `<optgroup>`, `hidden`
|
|
95
|
-
and `disabled`, labels the group with its text instead, so the label can
|
|
96
|
-
be a column of the group's first row.
|
|
97
|
-
- Its `value` selects the option with that key, including an option that
|
|
98
|
-
arrives after the value did.
|
|
99
|
-
|
|
100
|
-
`lb-picker` is the same class with the row template supplied by its
|
|
101
|
-
definition.
|
|
102
|
-
|
|
103
|
-
## `lb-picker`
|
|
104
|
-
|
|
105
|
-
`lb-options`, with the row template built in, for a list where every row is
|
|
106
|
-
one option showing one column:
|
|
107
|
-
|
|
108
|
-
```html
|
|
109
|
-
<lb-picker
|
|
110
|
-
lb-query="statuses"
|
|
111
|
-
lb-column="status"
|
|
112
|
-
lb-request="lb-row-update"
|
|
113
|
-
exp-label="Status"
|
|
114
|
-
exp-column="label"
|
|
115
|
-
></lb-picker>
|
|
39
|
+
npx loadbare-widgets skills install
|
|
116
40
|
```
|
|
117
41
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
| `exp-column` | The column each option shows |
|
|
122
|
-
|
|
123
|
-
An option built from two columns, a row with a second element, or options
|
|
124
|
-
in groups, is `lb-options` with the page's own templates.
|
|
125
|
-
|
|
126
|
-
## `lb-table`
|
|
127
|
-
|
|
128
|
-
A `<table>` that supplies its own scaffolding. The page supplies the heading
|
|
129
|
-
row, the row template, and optionally a footer, each as a `<template>`:
|
|
130
|
-
|
|
131
|
-
```html
|
|
132
|
-
<lb-table lb-query="ledger" exp-caption="Ledger">
|
|
133
|
-
<template lb-exp-template="head">
|
|
134
|
-
<tr><th>Date</th><th>Amount</th></tr>
|
|
135
|
-
</template>
|
|
136
|
-
<template lb-group>
|
|
137
|
-
<tr><th colspan="2" lb-column="month"></th></tr>
|
|
138
|
-
<template>
|
|
139
|
-
<tr><td lb-column="date"></td><td lb-column="amount"></td></tr>
|
|
140
|
-
</template>
|
|
141
|
-
</template>
|
|
142
|
-
<template lb-exp-template="foot">
|
|
143
|
-
<tr><td>Total</td><td lb-sum="amount"></td></tr>
|
|
144
|
-
</template>
|
|
145
|
-
</lb-table>
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
| Parameter | Fills |
|
|
149
|
-
|---------------|----------------------|
|
|
150
|
-
| `exp-caption` | The `<caption>` text |
|
|
151
|
-
|
|
152
|
-
| Template | Fills |
|
|
153
|
-
|-----------------------------------|-----------------------------------------|
|
|
154
|
-
| `<template lb-exp-template="head">` | The `<thead>` |
|
|
155
|
-
| `<template lb-exp-template="foot">` | The `<tfoot>` |
|
|
156
|
-
| Any other `<template>` | The row or group template, in the `<tbody>` |
|
|
157
|
-
|
|
158
|
-
- The hub places the rows by the query's order and builds its groups, and
|
|
159
|
-
leaves them where they stand for an edit from inside the table; see
|
|
160
|
-
[Rows the user is working in](./data-binding.md#rows-the-user-is-working-in). The
|
|
161
|
-
rows land in the one `<tbody>`, so a group here is a heading row with its
|
|
162
|
-
rows after it.
|
|
163
|
-
- `lb-order` and `lb-filter` go on the `lb-table` itself, beside
|
|
164
|
-
`lb-query`; see [Order](./data-binding.md#order) and
|
|
165
|
-
[Filters](./data-binding.md#filters).
|
|
166
|
-
- The footer is not a row of `ledger`. An aggregate there covers every row
|
|
167
|
-
showing;
|
|
168
|
-
a figure that is not a sum of the rows, such as a budget, is a `<tr>`
|
|
169
|
-
naming a `row` query of its own.
|
|
170
|
-
- A `<template lb-exp-template="ghost">` is a blank row for entering a new
|
|
171
|
-
one, in a `<tbody>` of its own. The widget joins its controls to a form
|
|
172
|
-
outside the table, since a `<form>` cannot wrap a `<tr>`, and puts the
|
|
173
|
-
cursor back in it once an insert from it succeeds.
|
|
174
|
-
- After rows land, the widget scrolls the row the page's own request created
|
|
175
|
-
or moved into view.
|
|
176
|
-
- Text selected in a cell whose `lb-column` the table's `lb-filter` names
|
|
177
|
-
becomes that column's filter in `lb-choices`: `=` for the whole text,
|
|
178
|
-
`^=` from its start, `$=` up to its end, `*=` otherwise.
|
|
179
|
-
- The heading of the order's leading column carries a triangle for the
|
|
180
|
-
direction, read from [`lb-query-order`](./data-binding.md#order). A
|
|
181
|
-
heading's column is the `lb-column` in the cell at its position in the row
|
|
182
|
-
template. While rows stand out of order the triangle carries
|
|
183
|
-
`data-unsorted` and a click on its heading re-sorts. With `lb-order`, a
|
|
184
|
-
click on the sorted heading reverses the order and a click on another
|
|
185
|
-
sorts by its column. Not on a grouped table.
|
|
186
|
-
|
|
187
|
-
## `lb-confirm`
|
|
188
|
-
|
|
189
|
-
A button that asks before it sends. The page writes the question inside the
|
|
190
|
-
tag, and the request goes on the dialog's confirm button, so nothing reaches
|
|
191
|
-
the hub until the user says yes:
|
|
192
|
-
|
|
193
|
-
```html
|
|
194
|
-
<lb-confirm exp-label="Delete" exp-request="lb-row-delete">
|
|
195
|
-
Delete <b lb-column="name"></b>?
|
|
196
|
-
</lb-confirm>
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
| Parameter | Fills |
|
|
200
|
-
|---------------|--------------------------------------------------|
|
|
201
|
-
| `exp-label` | The text of the button that opens the dialog |
|
|
202
|
-
| `exp-request` | The confirm button's `lb-request` |
|
|
203
|
-
| `exp-confirm` | The confirm button's text, `Confirm` when absent |
|
|
204
|
-
|
|
205
|
-
The widget closes the dialog once the request succeeds, and leaves it open
|
|
206
|
-
on a refusal.
|
|
207
|
-
|
|
208
|
-
## `lb-form`
|
|
209
|
-
|
|
210
|
-
A `<form>` over one row's controls. A row with a key saves each control's
|
|
211
|
-
column on `change`; a row whose key is empty is new, and the hub sends no
|
|
212
|
-
update for it, so its controls wait for a submit. A definition only.
|
|
213
|
-
|
|
214
|
-
| Parameter | Fills |
|
|
215
|
-
|-----------|-----------------|
|
|
216
|
-
| `exp-id` | The form's `id` |
|
|
217
|
-
|
|
218
|
-
## `lb-insert-dialog`
|
|
219
|
-
|
|
220
|
-
A row entered in a modal dialog, written once outside every row and opened
|
|
221
|
-
with `commandfor` and `command="show-modal"`. Save is the form's
|
|
222
|
-
`lb-row-insert`; on success the widget chooses the new row in the nearest
|
|
223
|
-
`lb-options` around the button that opened it, and closes. The handler
|
|
224
|
-
answers with a patch holding the new row.
|
|
225
|
-
|
|
226
|
-
While open, the button that opened it carries `insert-dialog-opener` and the
|
|
227
|
-
widget carries `anchored`, for a stylesheet to place the dialog beside the
|
|
228
|
-
button with CSS anchor positioning.
|
|
229
|
-
|
|
230
|
-
| Parameter | Fills |
|
|
231
|
-
|-------------|---------------------------------------------------|
|
|
232
|
-
| `exp-id` | The dialog's `id` |
|
|
233
|
-
| `exp-title` | The dialog's heading |
|
|
234
|
-
| `exp-query` | The form's `lb-query`, which it inserts into |
|
|
235
|
-
| `exp-save` | The Save button's text, `Save` when absent |
|
|
236
|
-
|
|
237
|
-
## `lb-master`
|
|
238
|
-
|
|
239
|
-
A set, one of its rows, and the buttons that act on the set: New, Copy,
|
|
240
|
-
Delete, Save new and Cancel, each shown only for a row on record or a new
|
|
241
|
-
one. A definition only, built from `lb-form` and `lb-confirm`. New sends
|
|
242
|
-
`new` and Copy sends `copy`, requests the page declares; `new` returns
|
|
243
|
-
`url()` emptying the parm that names the row.
|
|
244
|
-
|
|
245
|
-
| Parameter | Fills |
|
|
246
|
-
|---------------|--------------------------------------------|
|
|
247
|
-
| `exp-row` | The `lb-query` of the row the form shows |
|
|
248
|
-
| `exp-form-id` | The form's `id`, `master-form` when absent |
|
|
249
|
-
|
|
250
|
-
## `lb-checkbox`
|
|
251
|
-
|
|
252
|
-
A checkbox and its label as one element, for an application to style. A
|
|
253
|
-
definition only: a native checkbox is already a control (see
|
|
254
|
-
[Checkboxes](./data-binding.md#checkboxes)), so the widget is the markup, a
|
|
255
|
-
`<label>` holding the `<input type="checkbox">` and a `<span>` with the
|
|
256
|
-
text. The column and request go on the checkbox inside, so they arrive as
|
|
257
|
-
expansion attributes.
|
|
258
|
-
|
|
259
|
-
Unlike `lb-input`, it has no script making the tag the control. A value
|
|
260
|
-
that lands before a widget's script has loaded arrives only as the string
|
|
261
|
-
stamp `lb-column-value`, and a script checkbox would read `"false"` as
|
|
262
|
-
checked. The hub sets a native checkbox's `checked` directly.
|
|
263
|
-
|
|
264
|
-
| Parameter | Fills |
|
|
265
|
-
|---------------|-----------------------------------------------|
|
|
266
|
-
| `exp-column` | The checkbox's `lb-column` |
|
|
267
|
-
| `exp-label` | The label's text |
|
|
268
|
-
| `exp-request` | The checkbox's `lb-request`, none when absent |
|
|
269
|
-
|
|
270
|
-
## `lb-number` and `lb-date`
|
|
271
|
-
|
|
272
|
-
A number shown by the browser's `Intl.NumberFormat`, and a date or time
|
|
273
|
-
shown by `Intl.DateTimeFormat`. Neither is a control: `lb-column` goes on
|
|
274
|
-
the tag, and the widget renders the `lb-column-value` the hub stamps; see
|
|
275
|
-
[Receiving a value](./custom-elements.md#receiving-a-value).
|
|
276
|
-
|
|
277
|
-
```html
|
|
278
|
-
<lb-number lb-column="balance" exp-style="currency" exp-currency="USD"></lb-number>
|
|
279
|
-
<lb-date lb-column="due" exp-date-style="medium"></lb-date>
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
Each parameter is one of Intl's options in kebab-case, as `exp-currency-sign`
|
|
283
|
-
for `currencySign`, plus `exp-locale`. A value that is no number or date
|
|
284
|
-
shows as it arrived, and a date alone, `YYYY-MM-DD`, shows as that day in
|
|
285
|
-
every time zone. The stamp keeps the raw value, so a stylesheet selects on
|
|
286
|
-
it:
|
|
287
|
-
|
|
288
|
-
```css
|
|
289
|
-
lb-number[lb-column-value^="-"] { color: var(--negative); }
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
## `lb-unknown-page`
|
|
293
|
-
|
|
294
|
-
The chrome's dialog for a URL that names no page, as one tag:
|
|
295
|
-
|
|
296
|
-
```html
|
|
297
|
-
<lb-hub>
|
|
298
|
-
<nav>...</nav>
|
|
299
|
-
<main></main>
|
|
300
|
-
<lb-unknown-page></lb-unknown-page>
|
|
301
|
-
</lb-hub>
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
It expands to a `<dialog lb-url-unknown lb-query="lb-url">` showing
|
|
305
|
-
`lb-path`, and the hub opens it when no page's stub matches the path. See
|
|
306
|
-
[An unknown page](./chrome.md#an-unknown-page) for the same dialog written
|
|
307
|
-
by hand.
|
|
308
|
-
|
|
309
|
-
| Parameter | Fills |
|
|
310
|
-
|-------------------|------------------------------------------|
|
|
311
|
-
| `exp-button-text` | The text of the button that closes it, `OK` by default |
|
|
42
|
+
For a reader without the skill, the package's
|
|
43
|
+
[README](https://gitlab.com/kendowns/loadbare/-/blob/main/packages/widgets/README.md)
|
|
44
|
+
lists the widgets and links each page.
|
package/docs/testing.md
CHANGED
|
@@ -274,7 +274,8 @@ What the hub is tested for here:
|
|
|
274
274
|
a pending element is ignored
|
|
275
275
|
- a round trip the server never answers is aborted at the ten-second
|
|
276
276
|
deadline, under mocked timers, and fails the way any round trip fails
|
|
277
|
-
- a successful insert gathered from a form resets the form
|
|
277
|
+
- a successful insert gathered from a form resets the form, unless the
|
|
278
|
+
answer landed the new row on it
|
|
278
279
|
- a path with no page reports, lands `lb-page-unknown`, and opens the
|
|
279
280
|
`lb-url-unknown` dialog; two pages for one stub report and take the first
|
|
280
281
|
- `lb-url` lands with the path, the page's `lb-page-title` or stub as
|
|
@@ -90,7 +90,7 @@ publication — that's the same class shape
|
|
|
90
90
|
[Committing a Control](./080-widget-requests.md) already wrote, packaged and
|
|
91
91
|
given an import specifier instead of living in an application's `src/`.
|
|
92
92
|
It doesn't cover `lb-table`'s footer destination or `lb-picker`'s
|
|
93
|
-
expansion parameters, which
|
|
93
|
+
expansion parameters, which each widget's own page covers; see
|
|
94
94
|
[The Basic Widget Library](../reference/widgets.md).
|
|
95
95
|
|
|
96
96
|
---
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loadbare/app",
|
|
3
3
|
"description": "High performance web app framework for server-bound applications",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.22.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist",
|
|
@@ -22,7 +22,9 @@
|
|
|
22
22
|
"./constants": "./dist/core/lb-constants.js",
|
|
23
23
|
"./types": "./dist/core/lb-types.js",
|
|
24
24
|
"./server": "./dist/server/lb-server.js",
|
|
25
|
-
"./express": "./dist/server/lb-express.js"
|
|
25
|
+
"./express": "./dist/server/lb-express.js",
|
|
26
|
+
"./build": "./dist/build/build.js",
|
|
27
|
+
"./dev": "./dist/dev/lb-dev.js"
|
|
26
28
|
},
|
|
27
29
|
"scripts": {
|
|
28
30
|
"prepublishOnly": "npm run typecheck && npm run test && npm run build",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: loadbare-app
|
|
3
|
-
description: Build server-bound web applications with Loadbare/app. Covers the file conventions the builder finds by name (`chrome.html`, `*.page.html`, `*.queries.ts`, `*.requests.ts`, `imports.ts`, `<tag>.html`, `<tag>.browser.ts`); the `lb-*` attribute vocabulary that lands query rows on HTML and issues requests (`lb-query`, `lb-column`, `lb-show`, `lb-request`); queries declared with `row(key, run)` and `rows(key, run)`; the URL as the hub's own query `lb-url`, with `lb-url-link`, `lb-url-parm`, `lb-url-push` and `lb-url-unknown`; the user's order and filters as the hub's query `lb-choices`, read by `lb-order` and `lb-filter`; one form pointed at a row by the `--lb-edit`, `--lb-new` and `--lb-release` commands; re-sorting a list with `--lb-sort`; build-time expansion with `exp-*` parameters, `lb-exp-slot` and `lb-exp-template`; custom elements as form-associated controls and row hosts; the Express wiring with `hubRoutes`; and the `@loadbare/widgets` library. Use whenever a task involves `@loadbare/app`, `@loadbare/widgets`, `loadbare-app-build`, an `lb-` attribute, or a page, query, request or custom element file in a Loadbare application. The model is not React, htmx or REST, and cannot be inferred from them.
|
|
3
|
+
description: Build server-bound web applications with Loadbare/app. Covers the file conventions the builder finds by name (`chrome.html`, `*.page.html`, `*.queries.ts`, `*.requests.ts`, `imports.ts`, `<tag>.html`, `<tag>.browser.ts`); the `lb-*` attribute vocabulary that lands query rows on HTML and issues requests (`lb-query`, `lb-column`, `lb-show`, `lb-request`); queries declared with `row(key, run)` and `rows(key, run)`; the URL as the hub's own query `lb-url`, with `lb-url-link`, `lb-url-parm`, `lb-url-push` and `lb-url-unknown`; the user's order and filters as the hub's query `lb-choices`, read by `lb-order` and `lb-filter`; whether the page loaded and the server answers as the hub's query `lb-hub`; one form pointed at a row by the `--lb-edit`, `--lb-new` and `--lb-release` commands; re-sorting a list with `--lb-sort`; build-time expansion with `exp-*` parameters, `lb-exp-slot` and `lb-exp-template`; custom elements as form-associated controls and row hosts; the Express wiring with `hubRoutes`; and the `@loadbare/widgets` library. Use whenever a task involves `@loadbare/app`, `@loadbare/widgets`, `loadbare-app-build`, an `lb-` attribute, or a page, query, request or custom element file in a Loadbare application. The model is not React, htmx or REST, and cannot be inferred from them.
|
|
4
4
|
license: Apache-2.0
|
|
5
5
|
metadata:
|
|
6
6
|
package: "@loadbare/app"
|
|
@@ -48,7 +48,9 @@ carries, so their import-time code runs then; open a database in
|
|
|
48
48
|
`contextFor`, not at import. Then start the server: `createHub` refuses a page that declares a reserved name at startup,
|
|
49
49
|
and the server console reports a query that answers with the wrong kind.
|
|
50
50
|
Restart the server after adding or changing a `.queries.ts` or
|
|
51
|
-
`.requests.ts` file
|
|
51
|
+
`.requests.ts` file, or run it under the dev server, `devServer` from
|
|
52
|
+
`@loadbare/app/dev`, which rebuilds and restarts it after each change; see
|
|
53
|
+
[`references/dev-server.md`](references/dev-server.md).
|
|
52
54
|
|
|
53
55
|
## The shape of an application
|
|
54
56
|
|
|
@@ -73,7 +75,8 @@ server.ts
|
|
|
73
75
|
The chrome carries `<lb-hub>` inside `<body>`, an empty `<main>` inside the
|
|
74
76
|
hub, and `<script src="/client.js" defer>`. Everything a user touches sits
|
|
75
77
|
inside `<lb-hub>`. The chrome belongs to no page, so it names only the
|
|
76
|
-
hub's queries, `lb-url` and `lb-
|
|
78
|
+
hub's queries, `lb-url`, `lb-choices` and `lb-hub`, and sends no declared
|
|
79
|
+
request.
|
|
77
80
|
|
|
78
81
|
A page is an HTML fragment that lands in `<main>`:
|
|
79
82
|
|
|
@@ -217,6 +220,15 @@ text for contains. A choice shows with no round trip, then the server's
|
|
|
217
220
|
page changes. A filter that decides which rows the server sends is a query
|
|
218
221
|
parm.
|
|
219
222
|
|
|
223
|
+
**A page that failed to load says so.** The hub serves a third query,
|
|
224
|
+
`lb-hub`, and stamps its columns on `<lb-hub>` too: `lb-load-state`
|
|
225
|
+
(`loading`, `loaded`, `failed`), `lb-server-state` (`reachable`, `failing`,
|
|
226
|
+
`unreachable`), `lb-error` (`network`, `timeout` or the HTTP status),
|
|
227
|
+
`lb-pending` and `lb-as-of`. Show a server that is down from the chrome's
|
|
228
|
+
stylesheet, `lb-hub[lb-load-state="failed"] .load-failed`, rather than
|
|
229
|
+
leaving an empty page; see
|
|
230
|
+
[`references/chrome.md`](references/chrome.md#the-hubs-state).
|
|
231
|
+
|
|
220
232
|
**Groups are templates.** A `<template lb-group>` holds a heading and one
|
|
221
233
|
nested `<template>`, the next level or the row template; the nth breaks on
|
|
222
234
|
the order's nth term, to any depth. Contents land before the nested
|
|
@@ -475,12 +487,10 @@ and a condition need none. A custom element exists to be a control of its
|
|
|
475
487
|
own, or to act on rows once they land through the hook the hub calls,
|
|
476
488
|
`lbRowsLanded` (the `HubLifecycle` interface).
|
|
477
489
|
|
|
478
|
-
Before writing one, check `@loadbare/widgets
|
|
479
|
-
|
|
480
|
-
`lb-
|
|
481
|
-
|
|
482
|
-
form-associated controls that carry `lb-column` and `lb-request`
|
|
483
|
-
themselves. Install the package and list it in `src/imports.ts`:
|
|
490
|
+
Before writing one, check `@loadbare/widgets`, the basic widget set, which
|
|
491
|
+
the loadbare-widgets skill documents. Its controls are form-associated and
|
|
492
|
+
carry `lb-column` and `lb-request` themselves. Install the package and list
|
|
493
|
+
it in `src/imports.ts`:
|
|
484
494
|
|
|
485
495
|
```ts
|
|
486
496
|
export default ["@loadbare/widgets"];
|
|
@@ -510,9 +520,17 @@ with the package, so no network is needed.
|
|
|
510
520
|
the request context.
|
|
511
521
|
- [`references/builder.md`](references/builder.md) — the builder's options,
|
|
512
522
|
what it reads, and where it looks.
|
|
523
|
+
- [`references/dev-server.md`](references/dev-server.md) — `devServer` from
|
|
524
|
+
`@loadbare/app/dev`, and the parts to assemble another from.
|
|
513
525
|
- [`references/css.md`](references/css.md) — how stylesheets are ordered.
|
|
514
526
|
- [`references/widgets.md`](references/widgets.md) — the basic widget
|
|
515
|
-
library.
|
|
527
|
+
library as a package; each widget is in the loadbare-widgets skill.
|
|
516
528
|
- [`references/names.md`](references/names.md) — every name Loadbare
|
|
517
529
|
owns, the constants, and the section defining each. Check a name here
|
|
518
530
|
before designing around something the other references do not mention.
|
|
531
|
+
|
|
532
|
+
## The other loadbare skills
|
|
533
|
+
|
|
534
|
+
`npx loadbare-app skills install` puts this skill where a coding agent finds
|
|
535
|
+
it. `npx loadbare-widgets skills install` and `npx loadbare-db skills
|
|
536
|
+
install` do the same for the loadbare-widgets and loadbare-db skills.
|
|
@@ -16,19 +16,27 @@ loadbare-app-build [--src src] [--out dist] [--watch] [--minify]
|
|
|
16
16
|
| `--watch` | Build once, then again on every change under `--src` |
|
|
17
17
|
| `--minify` | Minify `client.js` and `app.css` |
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
During development, [the dev server](./dev-server.md) runs the build in
|
|
20
|
+
watch mode, and restarts the server when it needs to. To run the builder and
|
|
21
|
+
the server side by side without it, from the application's own
|
|
22
|
+
`package.json`:
|
|
20
23
|
|
|
21
24
|
```json
|
|
22
25
|
{
|
|
23
26
|
"scripts": {
|
|
24
|
-
"dev": "loadbare-app-build --watch & tsx server.ts"
|
|
27
|
+
"dev": "loadbare-app-build --watch & trap 'kill $! 2>/dev/null' EXIT INT TERM; tsx server.ts"
|
|
25
28
|
}
|
|
26
29
|
}
|
|
27
30
|
```
|
|
28
31
|
|
|
32
|
+
The trap stops the watcher when the server exits. Without it, a
|
|
33
|
+
backgrounded watcher ignores Ctrl-C under `sh` and outlives the server.
|
|
34
|
+
|
|
29
35
|
`--watch` watches every `.html`, `.ts`, and `.css` file under `--src`, and
|
|
30
|
-
reports a failed build to the console without stopping. It runs no
|
|
31
|
-
and reloads no browser.
|
|
36
|
+
reports a failed build to the console without stopping. It runs no server
|
|
37
|
+
and reloads no browser. A program that builds or watches as part of its own
|
|
38
|
+
work imports `buildApp` and `watchApp` from `@loadbare/app/build` instead;
|
|
39
|
+
see [Assembling your own](./dev-server.md#assembling-your-own).
|
|
32
40
|
|
|
33
41
|
`--minify` leaves `app.html` alone.
|
|
34
42
|
|
|
@@ -277,7 +277,58 @@ browser after a successful 200, and there is no server-delivered 404.
|
|
|
277
277
|
|
|
278
278
|
`@loadbare/widgets` ships this dialog as `<lb-unknown-page>`, for a chrome
|
|
279
279
|
that would rather write one tag; see
|
|
280
|
-
[The Basic Widget Library](./widgets.md
|
|
280
|
+
[The Basic Widget Library](./widgets.md).
|
|
281
|
+
|
|
282
|
+
## The hub's state
|
|
283
|
+
|
|
284
|
+
The hub serves a third query of its own, `lb-hub`: one row, keyed by
|
|
285
|
+
`lb-path`, saying whether the page's data arrived and whether the server
|
|
286
|
+
answers. A page whose load failed shows its markup with nothing landed on
|
|
287
|
+
it, and without this row nothing on the page can tell a list that is empty
|
|
288
|
+
from a server that is down.
|
|
289
|
+
|
|
290
|
+
| Column | Holds |
|
|
291
|
+
|-------------------|------------------------------------------------------------------------|
|
|
292
|
+
| `lb-load-state` | `loading`, `loaded` or `failed`: the page load for the URL showing |
|
|
293
|
+
| `lb-server-state` | `reachable`, `failing` or `unreachable`: how the latest round trip went |
|
|
294
|
+
| `lb-error` | Empty, or why the latest round trip failed |
|
|
295
|
+
| `lb-pending` | How many round trips are in flight, page loads and requests together |
|
|
296
|
+
| `lb-as-of` | When rows last came from the server, as an ISO timestamp |
|
|
297
|
+
|
|
298
|
+
- `lb-load-state` is `loading` while the page load is in flight, `loaded`
|
|
299
|
+
once the server answered it, and `failed` when it did not. A request whose
|
|
300
|
+
answer moves the URL and carries the page's queries loads the page too. A
|
|
301
|
+
load overtaken by a newer one says nothing, and a request that fails
|
|
302
|
+
later leaves the page `loaded`, since what it shows did arrive.
|
|
303
|
+
- `lb-server-state` is `reachable` when the server answered, a refusal
|
|
304
|
+
included; `failing` when it answered with an HTTP error status; and
|
|
305
|
+
`unreachable` when no answer came, because the network failed or the
|
|
306
|
+
ten-second deadline passed. It is empty until the first round trip
|
|
307
|
+
returns.
|
|
308
|
+
- `lb-error` is `network`, `timeout`, or the status the server answered
|
|
309
|
+
with, such as `500`. The next answer empties it.
|
|
310
|
+
- `lb-as-of` is unchanged by a refusal, which brings no rows.
|
|
311
|
+
|
|
312
|
+
The hub also stamps each column on `<lb-hub>` itself, as the attribute of
|
|
313
|
+
the same name, and leaves off one that is empty. A stylesheet reaches the
|
|
314
|
+
whole document that way, and the markup names the query only to show its
|
|
315
|
+
text:
|
|
316
|
+
|
|
317
|
+
```css
|
|
318
|
+
.load-failed { display: none; }
|
|
319
|
+
lb-hub[lb-load-state="failed"] .load-failed { display: block; }
|
|
320
|
+
lb-hub[lb-load-state="failed"] main { opacity: 0.4; }
|
|
321
|
+
lb-hub:not([lb-pending="0"]) .banner { cursor: progress; }
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
```html
|
|
325
|
+
<p class="load-failed" lb-query="lb-hub">
|
|
326
|
+
This page did not load: the server is <span lb-column="lb-server-state"></span>
|
|
327
|
+
(<span lb-column="lb-error"></span>).
|
|
328
|
+
</p>
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Nothing writes `lb-hub` but the hub. The builder refuses a request for it.
|
|
281
332
|
|
|
282
333
|
## Preventing the first-load blink
|
|
283
334
|
|
|
@@ -119,9 +119,9 @@ from its nearest ancestor row: the live row it is in, or the element a
|
|
|
119
119
|
it reads from that query's rows.
|
|
120
120
|
|
|
121
121
|
An element with `lb-query` and `lb-column` both shows the rows of its own
|
|
122
|
-
query and holds the column of the row around it. This
|
|
123
|
-
[
|
|
124
|
-
|
|
122
|
+
query and holds the column of the row around it. This `<lb-options>`, from
|
|
123
|
+
[`@loadbare/widgets`](./widgets.md), lists the accounts and holds its row's
|
|
124
|
+
`account`:
|
|
125
125
|
|
|
126
126
|
```html
|
|
127
127
|
<lb-options lb-query="accounts" lb-column="account">
|
|
@@ -167,8 +167,8 @@ option for the value shows no selection.
|
|
|
167
167
|
|
|
168
168
|
The hub hands every value to the browser as the server sent it. What a
|
|
169
169
|
number, a date or a null looks like is decided in the query, or by a custom
|
|
170
|
-
element that formats it, such as
|
|
171
|
-
[`
|
|
170
|
+
element that formats it, such as `lb-number` and `lb-date` in
|
|
171
|
+
[`@loadbare/widgets`](./widgets.md). Send a
|
|
172
172
|
column the user sorts or filters raw, and format it in the element.
|
|
173
173
|
|
|
174
174
|
### Checkboxes
|
|
@@ -944,7 +944,8 @@ nothing is not sent.
|
|
|
944
944
|
|
|
945
945
|
For a query the hub serves, `lb-url` or `lb-choices`, the hub answers
|
|
946
946
|
`lb-row-update` itself, with no round trip; see
|
|
947
|
-
[Query parms](./chrome.md#query-parms) and [Choices](#choices).
|
|
947
|
+
[Query parms](./chrome.md#query-parms) and [Choices](#choices). The third,
|
|
948
|
+
`lb-hub`, takes no request.
|
|
948
949
|
|
|
949
950
|
A key comes from a live row, or from an element a `row` landed on, so all
|
|
950
951
|
three work against either kind:
|
|
@@ -961,8 +962,11 @@ update from a form or a live row sends every control it gathers. The
|
|
|
961
962
|
application writes one `rowUpdate` for both, setting the columns `values`
|
|
962
963
|
names, as an SQL UPDATE does.
|
|
963
964
|
|
|
964
|
-
After a successful insert gathered from a form, the hub resets the form
|
|
965
|
-
|
|
965
|
+
After a successful insert gathered from a form, the hub resets the form,
|
|
966
|
+
unless the answer landed the new row on it. A form over a `row` query not
|
|
967
|
+
yet entered, whose insert answers `url()` to the new key, then shows the row
|
|
968
|
+
just saved, on record. A failed insert leaves the entry for the user to
|
|
969
|
+
correct.
|
|
966
970
|
|
|
967
971
|
Leave `lb-request` off a control inside a form or a live row that sends its
|
|
968
972
|
own update, or the same edit is written twice.
|
|
@@ -1254,7 +1258,9 @@ A reset of any form, whether the hub's, a reset button's or a script's,
|
|
|
1254
1258
|
returns its controls to their defaults, and the hub removes
|
|
1255
1259
|
`lb-column-value` from each of them. A cancelled reset keeps both.
|
|
1256
1260
|
|
|
1257
|
-
A page load that fails lands nothing and is reported to the console
|
|
1261
|
+
A page load that fails lands nothing and is reported to the console, and
|
|
1262
|
+
the query `lb-hub` says so; see [The hub's state](./chrome.md#the-hubs-state).
|
|
1263
|
+
A load
|
|
1258
1264
|
started by a request for `lb-url` stamps the element that sent it, as any
|
|
1259
1265
|
request stamps its element.
|
|
1260
1266
|
|