@loadbare/app 0.12.0 → 0.14.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.
Files changed (56) hide show
  1. package/dist/build/assemble.d.ts.map +1 -1
  2. package/dist/build/assemble.js +87 -1
  3. package/dist/build/assemble.js.map +1 -1
  4. package/dist/build/cli.js +2 -1
  5. package/dist/build/cli.js.map +1 -1
  6. package/dist/build/elements.d.ts +9 -1
  7. package/dist/build/elements.d.ts.map +1 -1
  8. package/dist/build/elements.js +50 -0
  9. package/dist/build/elements.js.map +1 -1
  10. package/dist/build/origins.d.ts +2 -0
  11. package/dist/build/origins.d.ts.map +1 -1
  12. package/dist/build/origins.js +1 -1
  13. package/dist/build/origins.js.map +1 -1
  14. package/dist/core/lb-constants.d.ts +34 -1
  15. package/dist/core/lb-constants.d.ts.map +1 -1
  16. package/dist/core/lb-constants.js +105 -0
  17. package/dist/core/lb-constants.js.map +1 -1
  18. package/dist/core/lb-types.d.ts +74 -18
  19. package/dist/core/lb-types.d.ts.map +1 -1
  20. package/dist/core/lb-types.js +74 -11
  21. package/dist/core/lb-types.js.map +1 -1
  22. package/dist/hub/lb-apply.d.ts +57 -18
  23. package/dist/hub/lb-apply.d.ts.map +1 -1
  24. package/dist/hub/lb-apply.js +661 -63
  25. package/dist/hub/lb-apply.js.map +1 -1
  26. package/dist/hub/lb-hub.browser.d.ts.map +1 -1
  27. package/dist/hub/lb-hub.browser.js +400 -33
  28. package/dist/hub/lb-hub.browser.js.map +1 -1
  29. package/dist/server/lb-express.d.ts +19 -7
  30. package/dist/server/lb-express.d.ts.map +1 -1
  31. package/dist/server/lb-express.js +62 -26
  32. package/dist/server/lb-express.js.map +1 -1
  33. package/dist/server/lb-server.d.ts +80 -11
  34. package/dist/server/lb-server.d.ts.map +1 -1
  35. package/dist/server/lb-server.js +185 -33
  36. package/dist/server/lb-server.js.map +1 -1
  37. package/docs/TECHREF-1.0.md +584 -111
  38. package/docs/comparison.md +17 -13
  39. package/docs/possible-ideas.md +308 -0
  40. package/docs/reference/chrome.md +7 -1
  41. package/docs/reference/custom-elements.md +134 -39
  42. package/docs/reference/data-binding.md +405 -17
  43. package/docs/reference/page-files.md +101 -19
  44. package/docs/reference/server.md +24 -0
  45. package/docs/reference/widgets.md +118 -25
  46. package/docs/roadmap.md +17 -6
  47. package/docs/testing.md +21 -10
  48. package/package.json +2 -3
  49. package/skills/loadbare-app/SKILL.md +92 -30
  50. package/skills/loadbare-app/references/TECHREF-1.0.md +584 -111
  51. package/skills/loadbare-app/references/chrome.md +7 -1
  52. package/skills/loadbare-app/references/custom-elements.md +134 -39
  53. package/skills/loadbare-app/references/data-binding.md +405 -17
  54. package/skills/loadbare-app/references/page-files.md +101 -19
  55. package/skills/loadbare-app/references/server.md +24 -0
  56. package/skills/loadbare-app/references/widgets.md +118 -25
@@ -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-push` and `lb-url-unknown`; 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-push` and `lb-url-unknown`; one form pointed at a row by the `--lb-edit`, `--lb-new` and `--lb-release` commands; 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"
@@ -176,14 +176,42 @@ from it.
176
176
 
177
177
  **A column never holds rows.** Master-detail is a `row` query and a `rows`
178
178
  query under two names. Many masters with their details is one `rows` query
179
- of joined rows, grouped for display by a custom element's `lbPlaceRow`. A
179
+ of joined rows, ordered by the master first and shown in groups. A
180
180
  query nested inside another query's row template receives the same rows in
181
- every outer row; use it for a picker, never for per-row detail. A new outer
181
+ every outer row; use it for a picker, never for per-row detail. Inside a
182
+ form, the live rows of a query nested in the form's own are gathered as
183
+ `rows: { <query>: [{ key, values }] }` beside `values`, so a master and a
184
+ subtable of its details (one input per type, say) are entered in one
185
+ submit, and the master's handler writes both. A new outer
182
186
  row is filled from the nested query's last answer, whatever order they land
183
187
  in.
184
188
 
189
+ **A `rows` query declares its order, and the hub places every row by it.**
190
+ `rows("id", run, { order: "category_order,name" })`; a column after `-` sorts
191
+ descending, and values compare by JSON type, so a numeric sort column is a
192
+ JSON number. The parm `lb-order-<query>` replaces the order, and a control
193
+ writing it inside `lb-query="lb-url"` re-sorts with no round trip. A query
194
+ that pages or limits reads the parm itself and declares
195
+ `serverSortedByUrl: true`. Never sort in a widget, and never send a
196
+ placeholder row to hold a place.
197
+
198
+ **Groups are templates.** A `<template lb-group>` holds a heading and one
199
+ nested `<template>`, the next level or the row template; the nth breaks on
200
+ the order's nth term, to any depth. Contents land before the nested
201
+ template, so put it inside the heading's element for a container and beside
202
+ the heading for a heading row. `<tbody>` and `<optgroup>` do not nest. The
203
+ heading is filled from the group's first row. `lb-count`, `lb-sum="col"`,
204
+ `lb-avg`, `lb-min` and `lb-max` total the nearest group, or the whole list
205
+ outside any.
206
+
207
+ **Animate with CSS.** The hub stamps `lb-row-created`, `lb-row-changed`,
208
+ `lb-row-moved`, and `lb-row-requested` for this page's request, and marks a
209
+ leaving row or group `lb-row-leaving` or `lb-group-leaving`, removing it once
210
+ its animations end. Scrolling to a row is script, in `lbRowsLanded`.
211
+
185
212
  **Every request has one shape.** `lb-request` names the request, and the
186
- hub sends `{ name, query, key, values }` as present: `query` from the
213
+ hub sends `{ name, query, key, values }` as present, with `keys` in place
214
+ of `key` for the rows the user selected: `query` from the
187
215
  nearest ancestor `lb-query`, `key` from the nearest ancestor row of that
188
216
  query, and `values` gathered from controls by their `lb-column`.
189
217
 
@@ -201,9 +229,10 @@ with `lb-column` gathers its own value alone. A `<form>` gathers every
201
229
  control whose form owner it is. An element in a live row gathers that live
202
230
  row. Anything else gathers its form owner's controls. A `<form>` cannot
203
231
  wrap a `<tr>`, so an insert row in a table puts its controls in a form
204
- elsewhere with the HTML `form` attribute. Checkboxes, radio buttons and
205
- file inputs are not controls here: they receive no value and are not
206
- gathered.
232
+ elsewhere with the HTML `form` attribute. A checkbox is a control: checked
233
+ unless its column is `false` or null, and gathered as `"true"` or `"false"`.
234
+ Radio buttons and file inputs are not controls here: they receive no value
235
+ and are not gathered.
207
236
 
208
237
  **A form that adds to a set chosen elsewhere is written once, outside every
209
238
  row.** A form cannot sit inside another form or in a table row, so a dialog
@@ -211,6 +240,17 @@ that creates an account while a posting's picker is choosing one goes at the
211
240
  end of the page, and each row opens it with `commandfor`. The dialog learns
212
241
  the new key from `lb-request-done`.
213
242
 
243
+ **A set the user edits has one form, pointed at a row.** Never put a form
244
+ in every row. Write one form naming the set's query, outside every row,
245
+ often in a `<dialog>`, and give it an `id`. A `type="button"` with
246
+ `commandfor="<id>"` and `command="--lb-edit"` in a live row fills it from
247
+ that row with no round trip; `--lb-new` starts it empty for an insert;
248
+ `--lb-release` lets it go. The form's `lb-key-value` is the row's key, empty
249
+ for a new row, absent when not in use, and a stylesheet shows Save or Save
250
+ new by it. A successful request from the form, or its dialog closing, lets
251
+ it go. Which row is being edited is never a query parm. A row that must be
252
+ fetched to be edited is another page, with that row as its master.
253
+
214
254
  **Three requests are Loadbare's.** `lb-row-insert` needs `query` and
215
255
  `values`, `lb-row-update` needs `query`, `key` and `values`, and
216
256
  `lb-row-delete` needs `query` and `key`. The page permits each under
@@ -219,6 +259,32 @@ Each works on a `row` query as well as a `rows` query, since the element a
219
259
  `row` lands on carries its key. Every other request name is a declared
220
260
  request, under `handlers`. Anything undeclared is refused.
221
261
 
262
+ **An empty key is a row not yet entered.** A `row` query answering with an
263
+ empty key, or a form `--lb-new` pointed, carries `lb-key-value=""`. The hub
264
+ sends inserts and declared requests from it with no `key`, and sends no
265
+ update or delete at all, silently. So a control with
266
+ `lb-request="lb-row-update"` saves on a row on record and only holds its
267
+ value on a new one. Never write script to stop such an update.
268
+
269
+ **Select rows with `lb-select`, never with a column.** An
270
+ `<input type="checkbox" lb-select>` in a row template selects its row; the
271
+ hub stamps `lb-row-selected`. A request for that query naming no one row,
272
+ such as a form outside the rows, carries the ticked rows as `keys`.
273
+ `rowUpdate` and `rowDelete` then run once per key with no new code; a
274
+ declared request gets `keys` itself. With none ticked an update or delete
275
+ is not sent. Success clears the selection, and so does `lb-show` hiding a
276
+ selector. A selecting mode kept in the URL reaches the rows as a column the
277
+ query computes from the parm.
278
+
279
+ **Refuse with `refusal()`, never with a plain throw.** `throw
280
+ refusal("message")`, `throw refusal({ column: "message" })` or both, from
281
+ `@loadbare/app/server`. The whole-request message lands as the
282
+ `lb-request-refused` stamp on the element that committed, shown by CSS
283
+ `attr()`; each column's message goes on its control by
284
+ `setCustomValidity`, and the first is reported. Editing anything the
285
+ request gathered withdraws it all. Any other throw is a failure with no
286
+ message, so a database error never reaches the page.
287
+
222
288
  **Write `rowUpdate` as a partial update.** A form sends every control it
223
289
  owns; a single control sends its one column. Set the columns `values`
224
290
  names, leave the rest alone, and check the names against the columns the
@@ -226,19 +292,16 @@ page may edit.
226
292
 
227
293
  **Return a patch when the change has a known extent.** `patch({ rows })`
228
294
  for rows added or edited, `patch({ drop })` for keys removed, with
229
- `refresh: []`. A refreshed `rows` query sends every row, and the hub places
230
- every row again, which moves each element and takes focus from the control
231
- the user is in. List a query in `refresh` only when its membership or order
232
- changed in a way the handler cannot name. Never list one only to fill the
295
+ `refresh: []`. A refreshed `rows` query sends every row to say what one row
296
+ could. List a query in `refresh` only when its membership changed in a way
297
+ the handler cannot name. Never list one only to fill the
233
298
  picker in a row the request adds: its answer did not change, and the hub
234
299
  fills a new row from the last one.
235
300
 
236
301
  **The usual reasons for a refresh each have a patch.**
237
- - A placeholder row standing in for an empty set or section: drop its key
238
- in the patch that adds the first real row, and add it back in the patch
239
- that drops the last.
240
- - A row whose position changes: the rows host places it, as `lb-table` does
241
- by `data-sort`.
302
+ - A row whose position changes: the hub places it by the query's order.
303
+ - A group that appears or goes: the hub makes it with its first row and
304
+ removes it with its last.
242
305
  - A row whose other columns change with the edit: re-read the row and patch
243
306
  it.
244
307
  - Rows the database removes with a deleted one: select their keys before
@@ -247,10 +310,8 @@ fills a new row from the last one.
247
310
  An update or a delete names its row by key, and removing a row never
248
311
  reorders the rest, so each always has a patch: `createHub` refuses at
249
312
  startup a `rowUpdate` or `rowDelete` whose `refresh` names its own `rows`
250
- query. An insert may refresh its own query, and should only when the new
251
- row's place matters and nothing places it: a patched row lands where its
252
- host puts it, in order under `lb-table` with `data-sort`, last in plain
253
- markup and in `lb-options`.
313
+ query. An insert may refresh its own query, though a patch of the new row
314
+ lands in its place by the order.
254
315
  Each handler's `refresh` is its own, and every query in it needs its own
255
316
  reason. A list shared by several handlers is a warning sign.
256
317
 
@@ -327,24 +388,24 @@ on `change`. Any other custom element keeps its content and receives the
327
388
  column as its `lb-column-value` attribute.
328
389
 
329
390
  **A custom element connects many times.** It is moved, never rebuilt: the
330
- hub places every live row again on each set of all rows, and parks an
331
- `lb-show` element in a template while it is off, so `connectedCallback` runs
332
- on every move. Listen on the element itself in the constructor, look a
391
+ hub moves a live row the order puts elsewhere, and parks an `lb-show`
392
+ element in a template while it is off, so `connectedCallback` runs on every
393
+ move. Listen on the element itself in the constructor, look a
333
394
  child up when it is needed, and in a control take up `lb-column-value` once,
334
395
  on first connect, since a value can land before the element upgrades.
335
396
 
336
397
  **The hub and a custom element talk in four ways, one per kind of
337
398
  message.** State the hub gives an element is an attribute stamp, or `value`
338
399
  on a control. Work the hub needs done while landing is an optional `lb`
339
- method: `lbPlaceRow`, `lbRowsLanded`. A moment is a bubbling event: an
400
+ method: `lbRowsLanded`. A moment is a bubbling event: an
340
401
  element sends `lb-request`, and the hub answers on the same element with
341
402
  `lb-request-done`, carrying the request and the response items that landed,
342
403
  or the error. Listen for `lb-request-done` on whichever ancestor needs the
343
404
  outcome, such as a dialog choosing the row its form just created.
344
405
 
345
406
  **A widget that holds rows may sit under `lb-show`.** Rows that land while
346
- it is away are placed by its `lbPlaceRow` once it first appears, so hide a
347
- table with `lb-show`, not with a stylesheet rule.
407
+ it is away are placed by the hub, and its `lbRowsLanded` runs once it first
408
+ appears, so hide a table with `lb-show`, not with a stylesheet rule.
348
409
 
349
410
  **Name a custom element script `<tag>.browser.ts`.** A plain `<tag>.ts`
350
411
  stays on the server and the tag goes unregistered.
@@ -372,12 +433,13 @@ parser loses the tag before the build can report it.
372
433
 
373
434
  Reach for one only when plain HTML cannot do the job. A set of rows, a form
374
435
  and a condition need none. A custom element exists to be a control of its
375
- own, or to place and scaffold rows through the two hooks the hub calls,
376
- `lbPlaceRow` and `lbRowsLanded` (the `RowsHost` interface).
436
+ own, or to act on rows once they land through the hook the hub calls,
437
+ `lbRowsLanded` (the `RowsHost` interface).
377
438
 
378
439
  Before writing one, check `@loadbare/widgets`: `lb-input`, `lb-select`,
379
- `lb-options`, `lb-picker`, `lb-table`, `lb-unknown-page`. The first four
380
- are form-associated controls that carry `lb-column` and `lb-request`
440
+ `lb-options`, `lb-picker`, `lb-table`, `lb-unknown-page`, `lb-confirm`,
441
+ `lb-form`, `lb-insert-dialog`, `lb-master`, `lb-checkbox`. The first four are
442
+ form-associated controls that carry `lb-column` and `lb-request`
381
443
  themselves. Install the package and list it in `src/imports.ts`:
382
444
 
383
445
  ```ts