@loadbare/app 0.23.0 → 0.25.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 (39) hide show
  1. package/dist/build/assemble.d.ts.map +1 -1
  2. package/dist/build/assemble.js +78 -1
  3. package/dist/build/assemble.js.map +1 -1
  4. package/dist/core/lb-constants.d.ts +8 -5
  5. package/dist/core/lb-constants.d.ts.map +1 -1
  6. package/dist/core/lb-constants.js +20 -11
  7. package/dist/core/lb-constants.js.map +1 -1
  8. package/dist/core/lb-types.d.ts +19 -3
  9. package/dist/core/lb-types.d.ts.map +1 -1
  10. package/dist/core/lb-types.js +35 -5
  11. package/dist/core/lb-types.js.map +1 -1
  12. package/dist/hub/lb-apply.d.ts +31 -22
  13. package/dist/hub/lb-apply.d.ts.map +1 -1
  14. package/dist/hub/lb-apply.js +186 -52
  15. package/dist/hub/lb-apply.js.map +1 -1
  16. package/dist/hub/lb-hub.browser.d.ts.map +1 -1
  17. package/dist/hub/lb-hub.browser.js +59 -28
  18. package/dist/hub/lb-hub.browser.js.map +1 -1
  19. package/dist/server/lb-server.d.ts +2 -2
  20. package/dist/server/lb-server.d.ts.map +1 -1
  21. package/dist/server/lb-server.js +29 -9
  22. package/dist/server/lb-server.js.map +1 -1
  23. package/docs/comparison.md +13 -11
  24. package/docs/miswarts.md +4 -3
  25. package/docs/reference/chrome.md +42 -0
  26. package/docs/reference/custom-elements.md +9 -4
  27. package/docs/reference/data-binding.md +143 -67
  28. package/docs/reference/names.md +11 -8
  29. package/docs/reference/page-files.md +11 -6
  30. package/docs/testing.md +3 -3
  31. package/package.json +1 -1
  32. package/skills/loadbare-app/SKILL.md +38 -15
  33. package/skills/loadbare-app/references/chrome.md +42 -0
  34. package/skills/loadbare-app/references/custom-elements.md +9 -4
  35. package/skills/loadbare-app/references/data-binding.md +143 -67
  36. package/skills/loadbare-app/references/miswarts.md +4 -3
  37. package/skills/loadbare-app/references/names.md +11 -8
  38. package/skills/loadbare-app/references/page-files.md +11 -6
  39. package/docs/temp-proposals.md +0 -251
@@ -66,7 +66,7 @@ A widget package declares these. An application never does.
66
66
 
67
67
  ## Attributes
68
68
 
69
- The developer writes seventeen attributes in pages and the chrome, and the
69
+ The developer writes eighteen attributes in pages and the chrome, and the
70
70
  builder refuses any other `lb-` attribute there. `lb-exp-slot` and
71
71
  `lb-exp-template` are written for expansion, which removes them before the
72
72
  check. The hub and the builder write the rest, as stamps, and script never
@@ -79,6 +79,7 @@ assigns one.
79
79
  | `lb-show` | Developer | [Conditional rendering](./data-binding.md#conditional-rendering) |
80
80
  | `lb-order` | Developer | [Order](./data-binding.md#order) |
81
81
  | `lb-filter` | Developer | [Filters](./data-binding.md#filters) |
82
+ | `lb-manual` | Developer | [Placing by hand](./data-binding.md#placing-by-hand) |
82
83
  | `lb-group` | Developer | [Groups](./data-binding.md#groups) |
83
84
  | `lb-count`, `lb-sum`, `lb-avg`, `lb-min`, `lb-max` | Developer | [Aggregates](./data-binding.md#aggregates) |
84
85
  | `lb-select` | Developer | [Selecting rows](./data-binding.md#selecting-rows) |
@@ -93,7 +94,7 @@ assigns one.
93
94
  | `lb-key-value` | Hub | [Landing](./data-binding.md#landing), [Editing a row in one form](./data-binding.md#editing-a-row-in-one-form) |
94
95
  | `lb-row-live` | Hub | [Landing](./data-binding.md#landing) |
95
96
  | `lb-query-row-count` | Hub | [Counting rows](./data-binding.md#counting-rows) |
96
- | `lb-query-unsorted-count`, `lb-row-unsorted` | Hub | [Rows the user is working in](./data-binding.md#rows-the-user-is-working-in) |
97
+ | `lb-query-unplaced-count`, `lb-row-unplaced` | Hub | [Placing by hand](./data-binding.md#placing-by-hand) |
97
98
  | `lb-query-order` | Hub | [Order](./data-binding.md#order) |
98
99
  | `lb-group-live`, `lb-group-column`, `lb-group-value` | Hub | [Groups](./data-binding.md#groups) |
99
100
  | `lb-row-created`, `lb-row-changed`, `lb-row-moved`, `lb-row-requested` | Hub | [What happened to a row](./data-binding.md#what-happened-to-a-row) |
@@ -138,9 +139,9 @@ Loadbare/app owns every value of HTML's `command` attribute beginning with
138
139
  | Command | Defined in |
139
140
  | -------------- | ------------------------------------------------------------------------ |
140
141
  | `--lb-edit` | [Editing a row in one form](./data-binding.md#editing-a-row-in-one-form) |
141
- | `--lb-new` | [Editing a row in one form](./data-binding.md#editing-a-row-in-one-form) |
142
+ | `--lb-new` | [Editing a row in one form](./data-binding.md#editing-a-row-in-one-form), [Rows not yet entered in a list](./data-binding.md#rows-not-yet-entered-in-a-list) |
142
143
  | `--lb-release` | [Editing a row in one form](./data-binding.md#editing-a-row-in-one-form) |
143
- | `--lb-sort` | [Rows the user is working in](./data-binding.md#rows-the-user-is-working-in) |
144
+ | `--lb-place` | [Placing by hand](./data-binding.md#placing-by-hand) |
144
145
 
145
146
  ## Reserved tags
146
147
 
@@ -199,7 +200,7 @@ imports them rather than writing a string.
199
200
  | `ATTR_ROW_LIVE` | `lb-row-live` |
200
201
  | `LIVE_ROW` | `[lb-row-live]`, the selector for a live row |
201
202
  | `ATTR_QUERY_ROW_COUNT` | `lb-query-row-count` |
202
- | `ATTR_QUERY_UNSORTED_COUNT` | `lb-query-unsorted-count` |
203
+ | `ATTR_QUERY_UNPLACED_COUNT` | `lb-query-unplaced-count` |
203
204
  | `ATTR_QUERY_ORDER` | `lb-query-order` |
204
205
  | `ATTR_GROUP` | `lb-group` |
205
206
  | `ATTR_GROUP_LIVE` | `lb-group-live` |
@@ -213,13 +214,15 @@ imports them rather than writing a string.
213
214
  | `CHOICES_QUERY` | `lb-choices` |
214
215
  | `ATTR_ORDER` | `lb-order` |
215
216
  | `ATTR_FILTER` | `lb-filter` |
217
+ | `ATTR_MANUAL` | `lb-manual` |
218
+ | `MANUAL_ORDER`, `MANUAL_FILTER` | `order`, `filter`: the sides `lb-manual` names |
216
219
  | `FILTER_OPERATORS` | Every filter operator, the longer first |
217
220
  | `ATTR_ROW_CREATED` | `lb-row-created` |
218
221
  | `ATTR_ROW_CHANGED` | `lb-row-changed` |
219
222
  | `ATTR_ROW_MOVED` | `lb-row-moved` |
220
223
  | `ATTR_ROW_REQUESTED` | `lb-row-requested` |
221
224
  | `REQUESTED_CREATED`, `REQUESTED_CHANGED`, `REQUESTED_MOVED` | `created`, `changed`, `moved` |
222
- | `ATTR_ROW_UNSORTED` | `lb-row-unsorted` |
225
+ | `ATTR_ROW_UNPLACED` | `lb-row-unplaced` |
223
226
  | `ATTR_ROW_LEAVING` | `lb-row-leaving` |
224
227
  | `ATTR_GROUP_LEAVING` | `lb-group-leaving` |
225
228
  | `ATTR_REQUEST` | `lb-request` |
@@ -229,7 +232,7 @@ imports them rather than writing a string.
229
232
  | `ATTR_REQUEST_ERROR` | `lb-request-error` |
230
233
  | `ATTR_REQUEST_REFUSED` | `lb-request-refused` |
231
234
  | `LB_REFUSAL_STATUS` | `422` |
232
- | `COMMAND_EDIT`, `COMMAND_NEW`, `COMMAND_RELEASE`, `COMMAND_SORT` | `--lb-edit`, `--lb-new`, `--lb-release`, `--lb-sort` |
235
+ | `COMMAND_EDIT`, `COMMAND_NEW`, `COMMAND_RELEASE`, `COMMAND_PLACE` | `--lb-edit`, `--lb-new`, `--lb-release`, `--lb-place` |
233
236
  | `LB_COMMANDS` | All four commands |
234
237
  | `LB_COMMAND_PREFIX` | `--lb-` |
235
238
  | `ATTR_ROW_EDITING` | `lb-row-editing` |
@@ -265,7 +268,7 @@ imports them rather than writing a string.
265
268
  | `ATTR_EXP_TEMPLATE` | `lb-exp-template` |
266
269
  | `ATTR_PAGE` | `lb-page` |
267
270
  | `ATTR_PAGE_TITLE` | `lb-page-title` |
268
- | `DEVELOPER_ATTRIBUTES` | The seventeen attributes a developer writes |
271
+ | `DEVELOPER_ATTRIBUTES` | The eighteen attributes a developer writes |
269
272
  | `HUB_TAG_NAME` | `lb-hub` |
270
273
  | `LB_ENDPOINT` | `/lb` |
271
274
  | `LB_REQUEST_TIMEOUT_MS` | `10000` |
@@ -273,8 +273,9 @@ reported and ignored. A declared request receives `keys` as it is.
273
273
  `rows` holds the rows of a query nested in the form the request came from,
274
274
  by query name, each with its `key` and the `values` of its own controls; see
275
275
  [A form over a set of rows](./data-binding.md#a-form-over-a-set-of-rows).
276
- The handler writes the master and its details together, deciding what each
277
- row's values mean, such as an empty amount being no row at all:
276
+ A row with `key: ""` is one not yet entered, added by `--lb-new`; insert
277
+ it. The handler writes the master and its details together, deciding what
278
+ each row's values mean, such as an empty amount being no row at all:
278
279
 
279
280
  ```ts
280
281
  rowInsert: {
@@ -382,8 +383,9 @@ one row dropped, one row edited — and leave `refresh` empty. A refreshed
382
383
  A change that seems to need a refresh usually has a patch:
383
384
 
384
385
  - A row whose position changes: the hub places it by the query's
385
- [order](./data-binding.md#order), or leaves it where the user is working
386
- when the request came from inside its list; a refresh would do the same.
386
+ [order](./data-binding.md#order), or leaves it where it stands under the
387
+ list's [`lb-manual`](./data-binding.md#placing-by-hand); a refresh would do
388
+ the same.
387
389
  - A group that appears or goes: the hub makes a group with its first row
388
390
  and removes it with its last, so no row stands in for an empty one.
389
391
  - A row whose other columns change with the edit: re-read the row and patch
@@ -445,7 +447,9 @@ export const requests: Requests = {
445
447
  ```
446
448
 
447
449
  A column other than `lb-path` is a query parm: set, or taken out when its
448
- value is an empty string. Name at least one column, and give each a string.
450
+ value is an empty string. Name at least one column, and give each a string,
451
+ or an array of strings to repeat the parm; see
452
+ [Several values](./chrome.md#several-values).
449
453
  With `lb-path` naming another page, the page is entered with only the parms
450
454
  named:
451
455
 
@@ -462,7 +466,8 @@ nothing else `run` returned is sent, since both answered for the URL the page
462
466
  left. The loaded page reads the new parms through `contextFor`; see
463
467
  [the Express server](./server.md#database-layer).
464
468
 
465
- - A `url()` naming no column, or holding a value that is not a string, is
469
+ - A `url()` naming no column, or holding a value that is neither a string
470
+ nor an array of strings, is
466
471
  warned about on the server console and ignored, and the refresh set runs
467
472
  as usual.
468
473
  - If loading the page fails, the write has still happened. The response
@@ -1,251 +0,0 @@
1
- # Proposals
2
-
3
- Working notes for changes not yet made. Not part of the skill.
4
-
5
- ## The mental model
6
-
7
- A `row` maps to an HTML form. It supports select, insert, update and delete.
8
- The hub handles the basics, such as resetting a form after an insert, and
9
- lifecycle methods let a custom element add behavior of its own.
10
-
11
- `rows` treats each of its rows as a `row`, and allows insert, update and
12
- delete of several rows at once. It also places its rows by sorting and
13
- filtering, each with an automatic or a manual flag.
14
-
15
- A form sends a parent `row` with its nested `rows` in one submit, and the
16
- handler writes them together. This is the foreign key.
17
-
18
- The URL names the page, and its query parms are the server's filters. The
19
- user's own sorts and filters are choices, held in `lb-choices`.
20
-
21
- Requests go up, from the element that committed through its ancestors to the
22
- hub, which completes them from what surrounds the element. Commands go
23
- sideways, by id to the element they name, carrying the button that sent them,
24
- and never reach the server. Lifecycle methods go down, from the hub to the
25
- custom elements it placed.
26
-
27
- What lies past this belongs to the application. It reaches the hub as fields
28
- a custom element supplies on a request, and through lifecycle methods the hub
29
- calls on a custom element.
30
-
31
- ## 1. Values kept across inserts
32
-
33
- Package: `@loadbare/widgets`. No change to `@loadbare/app`.
34
-
35
- ### Today
36
-
37
- After an insert succeeds, the hub resets the form the insert was gathered
38
- from, then calls `lbRequestDone` on the attached custom elements from the
39
- committing element outward. `detail.request.values` holds the values the
40
- insert sent, by column. A ghost row starts over empty, and each control
41
- returns to its HTML default.
42
-
43
- A page that wants some columns to carry over to the next row, such as a date
44
- or an account during a run of entries, has no way to say so.
45
-
46
- ### Proposal
47
-
48
- A widget around the list, `lb-keep` or similar, names the columns to keep:
49
-
50
- ```html
51
- <lb-keep exp-columns="date, account">
52
- <lb-table lb-query="entries">
53
- ...
54
- </lb-table>
55
- </lb-keep>
56
- ```
57
-
58
- In `lbRequestDone`, after a successful `lb-row-insert`, the widget sets each
59
- named column's control in the committing row back to the value the insert
60
- sent. The hub's reset and the refill run in one synchronous stretch, so the
61
- empty row is never painted.
62
-
63
- - A column not named returns to its HTML default: `value` on an input,
64
- `selected` on an option. A control with no default comes back blank.
65
- - A reset the user asks for, with a reset button, sends no request and is
66
- not followed by `lbRequestDone`. It clears every column.
67
- - Kept values live in the controls. A reload starts the row empty.
68
-
69
- ### Open
70
-
71
- - A starting value taken from the page, not from the last insert: ef's
72
- paychecks page enters a paycheck while showing a series, and the new
73
- paycheck's series is the one showing. A possible form is a default named
74
- as `query.column`.
75
- - Whether every wrapped control in `@loadbare/widgets` takes an HTML
76
- default.
77
-
78
- ## 2. Sorted and filtered placement
79
-
80
- Package: `@loadbare/app`.
81
-
82
- ### Today
83
-
84
- When a patch lands on a list, the hub either places the rows by the order and
85
- the filter, or holds them where they stand. It holds them when the request
86
- was sent from inside the list: the list is the nearest element carrying
87
- `lb-query` around the element that committed, or the request came from a form
88
- that `--lb-edit` pointed at one of its rows.
89
-
90
- Where the committing element sits is the only input to that decision. Two
91
- cases in ef come out wrong:
92
-
93
- - Matching. "Create rule and apply it" is a form in a side panel. Its answer
94
- patches the rows the rule matched, and under the filter "Unmatched only"
95
- they disappear. The user wants them to stay showing for review. An offset
96
- chosen with the form `--lb-edit` points at a row is held, so the two ways of
97
- matching a transaction behave differently.
98
- - Paychecks. "Change from here…" is a form pointed with `--lb-edit`, so its
99
- answer is held. The answer replaces the rest of the year, and the new
100
- paychecks land after the last row of the series, out of date order. The
101
- page carries a Re-sort button for this.
102
-
103
- Neither table has edits in its rows. Every edit on both is made in a form
104
- outside the table.
105
-
106
- ### Proposal
107
-
108
- The element carrying `lb-query` declares each kind of placement, `auto` or
109
- `manual`. Both default to `auto`. Spelling is open; for illustration:
110
-
111
- ```html
112
- <lb-table lb-query="entries" lb-order="entries_order"
113
- lb-filter="description, txn_date, is_unmatched"
114
- lb-order-placement="manual" lb-filter-placement="manual">
115
- ```
116
-
117
- The rule about where a request was sent from is removed.
118
-
119
- Each line of today's held behavior falls under one flag:
120
-
121
- | The answer | `manual` | Flag |
122
- | -------------------------------------- | ---------------------------------- | ------ |
123
- | Changes a column the order reads | The row stays where it stands | order |
124
- | Creates a row | The row goes last in its group | order |
125
- | Changes the column its group breaks on | The row stays under its heading | order |
126
- | Changes a row so the filter hides it | The row stays showing | filter |
127
- | Drops a row | The row leaves, under either value | — |
128
-
129
- Under `auto`, the rows are placed by the order and the filter on every
130
- landing.
131
-
132
- Every combination has a use:
133
-
134
- | Order | Filter | Example |
135
- | -------- | -------- | -------------------------------------------------------- |
136
- | `auto` | `auto` | Paychecks: a regenerated schedule lands in date order |
137
- | `manual` | `manual` | Matching: answered rows stay in place for review |
138
- | `auto` | `manual` | Answered rows stay showing and move into the order |
139
- | `manual` | `auto` | A to-do list: an edit does not move a row, done hides it |
140
-
141
- A row left where the order or the filter would not leave it is stamped, as
142
- `lb-row-unsorted` is today, and counted in `lb-query-unsorted-count`. The rows
143
- are placed by both again when the page loads, when the user's order or filter
144
- changes, and on `--lb-sort`.
145
-
146
- ### The command
147
-
148
- `--lb-sort` today places the rows by both the order and the filter, so a row
149
- kept despite the filter leaves on it. Under the flags it is renamed for what
150
- it does, `--lb-place` or similar.
151
-
152
- A side set to `auto` is in place after every landing, so one command does
153
- what each list needs:
154
-
155
- | Order | Filter | The command |
156
- | -------- | -------- | ----------------- |
157
- | `manual` | `auto` | Sorts |
158
- | `auto` | `manual` | Filters |
159
- | `manual` | `manual` | Sorts and filters |
160
- | `auto` | `auto` | Changes nothing |
161
-
162
- Separate `--lb-sort` and `--lb-filter` differ from it only when both sides are
163
- `manual` and the user applies one without the other. No case for that is in
164
- hand.
165
-
166
- ### Effect on ef
167
-
168
- - Matching declares both `manual`. The rule's answer and the offset form
169
- behave alike, wherever the form sits.
170
- - Paychecks declares nothing. The Re-sort button and its comment are removed.
171
-
172
- ### Effect on other pages
173
-
174
- A list that relies on being held today, such as an editable `lb-table` with a
175
- ghost row, declares `manual` to keep its behavior. Under `auto`, a row edited
176
- in place moves into the order, and a row entered in the ghost row is placed by
177
- the order.
178
-
179
- ### Open
180
-
181
- - The attribute names.
182
- - One stamp for both kinds of out-of-place row, or one for each, so a page can
183
- style a row out of order apart from a row kept despite the filter. The
184
- commands follow the stamps. One stamp has one count, one button shown while
185
- it is not 0, and one command. Two stamps let a page show Re-sort and
186
- Re-filter apart, each with its own command, `--lb-sort` and `--lb-filter`,
187
- beside the one for both. Every name carries the `--` prefix, or the
188
- browser ignores it.
189
-
190
- ## 3. Child rows entered with their parent
191
-
192
- Package: `@loadbare/app`.
193
-
194
- ### Today
195
-
196
- A form gathers the live rows of a query nested in its own, and sends them in
197
- `rows` beside its own `values`. The handler writes the parent and its child
198
- rows together. A live row is one the nested query answered, so the child rows
199
- exist before the form is sent: ef's paycheck form sends one amount per
200
- deduction type, and the types come from the database.
201
-
202
- A row not yet entered, carrying `lb-key-value=""`, arises only as a single
203
- row: a `row` query answering with an empty key, or a form pointed by
204
- `--lb-new`. A list holds no row not yet entered.
205
-
206
- ptracking's flight page enters a flight, then its arrivals. The arrivals
207
- section shows once the flight is on record, and each arrival is its own
208
- `lb-row-insert` from the ghost row, keyed by the `flight_id` parm. The
209
- arrivals handler refuses an insert with no flight: "Save the flight first."
210
- Most flights have one arrival, and pattern work is one arrival with a
211
- quantity, so the usual entry is two saves and a second form.
212
-
213
- ### Proposal
214
-
215
- A list may hold rows not yet entered.
216
-
217
- 1. Inside a parent not yet entered, the list's Add puts a row not yet entered
218
- into the list, and sends nothing.
219
- 2. The parent's form gathers those rows with its insert, each with no key,
220
- under the nested query's name in `rows`.
221
- 3. The parent's handler inserts the parent and its child rows in one
222
- transaction, and answers both. The rows not yet entered are replaced by
223
- the rows the answer lands.
224
- 4. Once the parent is on record, the list's Add inserts as it does today.
225
-
226
- A row not yet entered in a list follows the existing rules for one:
227
-
228
- - Its controls carrying `lb-request="lb-row-update"` send nothing and hold
229
- what the parent's submit gathers. Once the row is on record, they save as
230
- they change.
231
- - A delete from it sends nothing. The row is removed from the list.
232
- - A refusal of the parent's insert leaves it in place, and a column's message
233
- goes on its control, as for any control the request gathered.
234
-
235
- ### Effect on ptracking
236
-
237
- - The arrivals list moves inside the flight's form, and loses
238
- `lb-show="on_record"`.
239
- - The flight's `rowInsert` accepts `rows.arrivals` and inserts both.
240
- `detailCrud` writes the parent alone today.
241
- - A flight with one arrival is one save. A flight with three approaches is
242
- three rows not yet entered and one save.
243
-
244
- ### Open
245
-
246
- - The command that adds a row not yet entered: the ghost row's insert,
247
- changing meaning while the parent is not on record, or a command of its own.
248
- - `lb-table` joins the ghost row's controls to a form of its own, outside the
249
- table, with the `form` attribute. A ghost row inside a parent's form then
250
- belongs to the ghost row's form, not the parent's.
251
- - One level only, as for a form over a set of rows today.