@loadbare/app 0.9.0 → 0.11.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 +3 -3
- package/dist/build/assemble.d.ts.map +1 -1
- package/dist/build/assemble.js +107 -90
- package/dist/build/assemble.js.map +1 -1
- package/dist/build/expand.d.ts +6 -1
- package/dist/build/expand.d.ts.map +1 -1
- package/dist/build/expand.js +112 -26
- package/dist/build/expand.js.map +1 -1
- package/dist/build/locations.d.ts +2 -3
- package/dist/build/locations.d.ts.map +1 -1
- package/dist/build/locations.js +2 -3
- package/dist/build/locations.js.map +1 -1
- package/dist/build/pages.d.ts +3 -4
- package/dist/build/pages.d.ts.map +1 -1
- package/dist/build/pages.js +3 -4
- package/dist/build/pages.js.map +1 -1
- package/dist/core/lb-constants.d.ts +27 -24
- package/dist/core/lb-constants.d.ts.map +1 -1
- package/dist/core/lb-constants.js +103 -168
- package/dist/core/lb-constants.js.map +1 -1
- package/dist/core/lb-types.d.ts +64 -77
- package/dist/core/lb-types.d.ts.map +1 -1
- package/dist/core/lb-types.js +40 -7
- package/dist/core/lb-types.js.map +1 -1
- package/dist/hub/lb-apply.d.ts +47 -37
- package/dist/hub/lb-apply.d.ts.map +1 -1
- package/dist/hub/lb-apply.js +195 -199
- package/dist/hub/lb-apply.js.map +1 -1
- package/dist/hub/lb-hub.browser.d.ts +1 -1
- package/dist/hub/lb-hub.browser.d.ts.map +1 -1
- package/dist/hub/lb-hub.browser.js +410 -449
- package/dist/hub/lb-hub.browser.js.map +1 -1
- package/dist/server/lb-express.d.ts +5 -5
- package/dist/server/lb-express.d.ts.map +1 -1
- package/dist/server/lb-express.js +35 -66
- package/dist/server/lb-express.js.map +1 -1
- package/dist/server/lb-server.d.ts +77 -135
- package/dist/server/lb-server.d.ts.map +1 -1
- package/dist/server/lb-server.js +132 -79
- package/dist/server/lb-server.js.map +1 -1
- package/docs/TECHREF-1.0.md +908 -585
- package/docs/comparison.md +243 -185
- package/docs/prior-art.md +15 -14
- package/docs/reference/builder.md +9 -3
- package/docs/reference/chrome.md +107 -56
- package/docs/reference/custom-elements.md +291 -173
- package/docs/reference/data-binding.md +381 -374
- package/docs/reference/overview.md +12 -10
- package/docs/reference/page-files.md +164 -99
- package/docs/reference/server.md +2 -2
- package/docs/reference/widgets.md +104 -110
- package/docs/roadmap.md +32 -39
- package/docs/terms-of-art.md +57 -0
- package/docs/testing.md +97 -68
- package/docs/theory.md +92 -58
- package/docs/tutorials/010-pages-and-navigation.md +20 -12
- package/docs/tutorials/020-css.md +6 -3
- package/docs/tutorials/030-html-decomposition.md +9 -7
- package/docs/tutorials/040-displaying-data.md +30 -13
- package/docs/tutorials/{050-actions.md → 050-requests.md} +25 -15
- package/docs/tutorials/060-custom-element-code.md +17 -16
- package/docs/tutorials/065-conditional-rendering.md +34 -23
- package/docs/tutorials/070-displaying-a-list.md +29 -21
- package/docs/tutorials/072-inserting-into-a-list.md +24 -16
- package/docs/tutorials/074-deleting-from-a-list.md +9 -7
- package/docs/tutorials/076-updating-a-list-item.md +11 -10
- package/docs/tutorials/080-widget-requests.md +71 -43
- package/docs/tutorials/090-using-widget-libraries.md +22 -22
- package/docs/what-does-loadbare-extend.md +124 -0
- package/package.json +1 -1
- package/skills/loadbare-app/SKILL.md +201 -123
- package/skills/loadbare-app/references/TECHREF-1.0.md +908 -585
- package/skills/loadbare-app/references/builder.md +9 -3
- package/skills/loadbare-app/references/chrome.md +107 -56
- package/skills/loadbare-app/references/custom-elements.md +291 -173
- package/skills/loadbare-app/references/data-binding.md +381 -374
- package/skills/loadbare-app/references/overview.md +12 -10
- package/skills/loadbare-app/references/page-files.md +164 -99
- package/skills/loadbare-app/references/server.md +2 -2
- package/skills/loadbare-app/references/widgets.md +104 -110
- package/docs/analysis-accidental-complexity.md +0 -149
- package/docs/analysis-closed-set.md +0 -210
package/docs/prior-art.md
CHANGED
|
@@ -32,14 +32,14 @@ table repetition agent. A DSO might take "an Open Database Connectivity
|
|
|
32
32
|
(ODBC) connection string and an Structured Query Language (SQL) statement,"
|
|
33
33
|
and had to expose its data through OLE DB.
|
|
34
34
|
|
|
35
|
-
| IE4
|
|
36
|
-
|
|
37
|
-
| `DATASRC` on a table repeats "an entire set of records" ("set binding")
|
|
38
|
-
| A single-valued consumer takes one value "from the current record"
|
|
39
|
-
| `DATAFLD` names "a column in the data set"
|
|
40
|
-
| The repetition agent "uses the table row (tr) in the table body as a template" | `<template
|
|
41
|
-
| The DSO's SQL statement
|
|
42
|
-
| The binding agent "work[s] completely behind the scenes"
|
|
35
|
+
| IE4 | Loadbare |
|
|
36
|
+
|--------------------------------------------------------------------------------|-------------------------------------|
|
|
37
|
+
| `DATASRC` on a table repeats "an entire set of records" ("set binding") | `lb-query` naming a `rows` query |
|
|
38
|
+
| A single-valued consumer takes one value "from the current record" | `lb-query` naming a `row` query |
|
|
39
|
+
| `DATAFLD` names "a column in the data set" | `lb-column` |
|
|
40
|
+
| The repetition agent "uses the table row (tr) in the table body as a template" | the row template, a `<template>` |
|
|
41
|
+
| The DSO's SQL statement | a page's queries |
|
|
42
|
+
| The binding agent "work[s] completely behind the scenes" | the hub |
|
|
43
43
|
|
|
44
44
|
It differed from Loadbare in three ways:
|
|
45
45
|
|
|
@@ -156,13 +156,14 @@ Sources:
|
|
|
156
156
|
**Loadbare only:**
|
|
157
157
|
|
|
158
158
|
- The server is the source of truth, and the hub holds no data.
|
|
159
|
-
- A response says what changed, as
|
|
160
|
-
is observed.
|
|
161
|
-
- Writes are requests (`lb-
|
|
162
|
-
back.
|
|
159
|
+
- A response says what changed, as response items holding all rows, a patch
|
|
160
|
+
or a row, so nothing is observed.
|
|
161
|
+
- Writes are requests (`lb-request`, naming a declared request or one of the
|
|
162
|
+
row requests Loadbare provides) whose answers land back.
|
|
163
163
|
- A request's position is read from the document.
|
|
164
164
|
- A build step: expansion, tree shaking, pages shipped as templates.
|
|
165
|
-
-
|
|
165
|
+
- The URL and request state carried by the hub, the URL as a query of its
|
|
166
|
+
own.
|
|
166
167
|
|
|
167
168
|
Two of Loadbare's central decisions reject what ended MDV. There is no
|
|
168
169
|
client-side model to observe, which is what made `Object.observe` too slow in
|
|
@@ -195,7 +196,7 @@ current (Polymer, React). No source found keeps the branch in a template in
|
|
|
195
196
|
the document, standing where the element stood, with no framework cache. The
|
|
196
197
|
hub has nowhere else to keep one.
|
|
197
198
|
|
|
198
|
-
Loadbare's recommendation before `lb-show`, a stylesheet rule on `lb-value`,
|
|
199
|
+
Loadbare's recommendation before `lb-show`, a stylesheet rule on `lb-column-value`,
|
|
199
200
|
is the same family as Polymer's `dom-if` and MDV's `hidden?`: the element stays and
|
|
200
201
|
CSS hides it.
|
|
201
202
|
|
|
@@ -122,11 +122,17 @@ A tag with neither a script nor a definition in any origin is an error.
|
|
|
122
122
|
| `app.css` | Every stylesheet, concatenated |
|
|
123
123
|
| `pages.ts` | The `hub` the server passes to `hubRoutes` |
|
|
124
124
|
|
|
125
|
-
The builder expands the chrome and every page against the available
|
|
125
|
+
The builder expands the chrome and every page against the available
|
|
126
126
|
definitions — see [Custom Elements](./custom-elements.md#html) for the
|
|
127
127
|
substitution rules — wraps each expanded page in
|
|
128
|
-
`<template lb-page="<
|
|
129
|
-
|
|
128
|
+
`<template lb-page="<stub>">`, and splices them into the chrome's `<body>`.
|
|
129
|
+
It removes a page file's `<title>` and stamps its text on the page's
|
|
130
|
+
template as `lb-page-title`; see [The page title](./page-files.md#the-page-title).
|
|
131
|
+
It formats the result with Prettier when the application has it installed.
|
|
132
|
+
|
|
133
|
+
The builder checks the `lb-` attributes of the chrome and every page after
|
|
134
|
+
expansion, and stops on the first file with a problem; see
|
|
135
|
+
[The markup checks](./data-binding.md#the-markup-checks).
|
|
130
136
|
|
|
131
137
|
The builder writes `app.css` only when it finds a stylesheet, and `pages.ts`
|
|
132
138
|
only when some page has a `.requests.ts` or a `.queries.ts` file. Import `hub`
|
package/docs/reference/chrome.md
CHANGED
|
@@ -9,7 +9,7 @@ anywhere in the `src/` tree. Any directory will do.
|
|
|
9
9
|
|
|
10
10
|
## A complete chrome
|
|
11
11
|
|
|
12
|
-
Here is a minimal but
|
|
12
|
+
Here is a minimal but complete chrome for a typical app:
|
|
13
13
|
|
|
14
14
|
```html
|
|
15
15
|
<!-- src/chrome.html -->
|
|
@@ -24,18 +24,18 @@ Here is a minimal but fully complaint chrome for a typical app:
|
|
|
24
24
|
</head>
|
|
25
25
|
<body hidden>
|
|
26
26
|
<lb-hub>
|
|
27
|
-
<header lb-
|
|
27
|
+
<header lb-query="lb-url">
|
|
28
28
|
<h1>Membership Roster</h1>
|
|
29
|
-
<h2 lb-
|
|
29
|
+
<h2 lb-column="lb-page-label"></h2>
|
|
30
30
|
</header>
|
|
31
31
|
<nav>
|
|
32
|
-
<a href="/" lb-
|
|
33
|
-
<a href="/members" lb-
|
|
32
|
+
<a href="/" lb-url-link>Home</a>
|
|
33
|
+
<a href="/members" lb-url-link>Members</a>
|
|
34
34
|
<a href="https://example.org/">Our website</a>
|
|
35
35
|
</nav>
|
|
36
36
|
<main></main>
|
|
37
|
-
<dialog lb-unknown
|
|
38
|
-
The URL <span lb-
|
|
37
|
+
<dialog lb-url-unknown lb-query="lb-url">
|
|
38
|
+
The URL <span lb-column="lb-path"></span> is not in this app.
|
|
39
39
|
</dialog>
|
|
40
40
|
</lb-hub>
|
|
41
41
|
</body>
|
|
@@ -52,81 +52,133 @@ The chrome is plain HTML; nothing in it is generated or templated.
|
|
|
52
52
|
| A complete HTML document | Doctype, `<html>`, `<head>`, `<body>` |
|
|
53
53
|
| `<lb-hub>` inside `<body>` | The application's live element |
|
|
54
54
|
| An empty `<main>` inside `<lb-hub>` | Holds the current page |
|
|
55
|
-
| `<script src="/client.js" defer>` | Defines `<lb-hub>` and every other
|
|
55
|
+
| `<script src="/client.js" defer>` | Defines `<lb-hub>` and every other custom element |
|
|
56
56
|
|
|
57
57
|
Everything else is optional:
|
|
58
58
|
|
|
59
59
|
| Optional | Description |
|
|
60
60
|
|-------------------------------------------|---------------------------------------------|
|
|
61
61
|
| `<link rel="stylesheet" href="/app.css">` | The bundled stylesheet |
|
|
62
|
-
| `<a lb-
|
|
63
|
-
| `lb-
|
|
64
|
-
| `<dialog lb-unknown
|
|
65
|
-
| Custom elements | The chrome, decomposed into
|
|
62
|
+
| `<a lb-url-link>` | A link between pages |
|
|
63
|
+
| `lb-query="lb-url"` | Where the page is — see below |
|
|
64
|
+
| `<dialog lb-url-unknown>` | A message when a URL matches no page |
|
|
65
|
+
| Custom elements | The chrome, decomposed into element files |
|
|
66
66
|
| `<body hidden>` + a `<noscript>` fallback | Avoids a first-load blink — see below |
|
|
67
67
|
| Any other HTML | Header, footer, skip links, meta tags, etc. |
|
|
68
68
|
|
|
69
|
-
## Rules for writing chrome
|
|
69
|
+
## Rules for writing chrome
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
Put everything the user interacts with inside `<lb-hub>`. The hub normally
|
|
72
72
|
sits directly inside `<body>`, with banner, nav, footer and `<main>` inside
|
|
73
73
|
it, so Loadbare can act on all of them.
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
[Query parms](./data-binding.md#query-parms). A bare `/` resolves to `index`, so the
|
|
79
|
-
landing page is the one named `index.page.html`. An anchor without
|
|
80
|
-
`lb-nav-link` is left alone and behaves like any other link.
|
|
75
|
+
The chrome's `<title>` is the document title until the first page shows.
|
|
76
|
+
From then on the hub sets the document title to the page's label; see
|
|
77
|
+
[The URL](#the-url).
|
|
81
78
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
path names no page. What it says is up to the chrome:
|
|
85
|
-
the dialog is a subtree like any other, and it displays where the page is by
|
|
86
|
-
naming the hub's own query, described next.
|
|
79
|
+
Put `lb-url-unknown` on a `<dialog>` inside `<lb-hub>`; the builder rejects
|
|
80
|
+
it anywhere else.
|
|
87
81
|
|
|
88
|
-
##
|
|
82
|
+
## The URL
|
|
89
83
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
row
|
|
93
|
-
shows a value — so a chrome displays the current page with no code at all:
|
|
84
|
+
The hub serves one query of its own, `lb-url`, of kind `row`, keyed by
|
|
85
|
+
`lb-path`. It lands on every element inside the hub that names it, the way a
|
|
86
|
+
server's row lands, so a chrome shows where the page is with no code:
|
|
94
87
|
|
|
95
88
|
```html
|
|
96
|
-
<header lb-
|
|
89
|
+
<header lb-query="lb-url">
|
|
97
90
|
<h1>Membership Roster</h1>
|
|
98
|
-
<h2 lb-
|
|
91
|
+
<h2 lb-column="lb-page-label"></h2>
|
|
99
92
|
</header>
|
|
100
93
|
```
|
|
101
94
|
|
|
102
|
-
|
|
|
103
|
-
|
|
104
|
-
| `
|
|
105
|
-
| `page-
|
|
95
|
+
| Column | Holds |
|
|
96
|
+
|-------------------|---------------------------------------------------------|
|
|
97
|
+
| `lb-path` | The path, such as `/members`. The row's key |
|
|
98
|
+
| `lb-page-label` | The page's title, or its stub when it has none |
|
|
99
|
+
| `lb-page-unknown` | `true` when no page's stub matches the path |
|
|
100
|
+
| Any other name | The query parm of that name, or empty when it is absent |
|
|
106
101
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
102
|
+
A path names a page by its stub: `/members` shows `members.page.html`, and
|
|
103
|
+
`/` shows `index.page.html`. A page's title is the text of the `<title>` its
|
|
104
|
+
page file carries; see [page files](./page-files.md#the-page-title). The hub
|
|
105
|
+
sets the document title to `lb-page-label` whenever it is not null, so the
|
|
106
|
+
tab and the browser history show the page.
|
|
112
107
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
subtree names it, so a chrome that displays no navigation is not warned
|
|
116
|
-
about a query with no scope.
|
|
108
|
+
`lb-url` is the one query a page may use that the server does not declare. A
|
|
109
|
+
page names it the same way, anywhere inside the hub.
|
|
117
110
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
111
|
+
### Links
|
|
112
|
+
|
|
113
|
+
Write `lb-url-link` on an `<a>` to move between pages:
|
|
114
|
+
|
|
115
|
+
```html
|
|
116
|
+
<nav>
|
|
117
|
+
<a href="/" lb-url-link>Home</a>
|
|
118
|
+
<a href="/members?team=Engines" lb-url-link>Engines</a>
|
|
119
|
+
</nav>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
On a plain primary click, the hub pushes a history entry for the `href`,
|
|
123
|
+
path and query string both, and shows the page it names. A click with a
|
|
124
|
+
modifier key or another button, and a link without `lb-url-link`, behave as
|
|
125
|
+
the browser has them behave. Back and Forward show the page at the URL they
|
|
126
|
+
arrive at.
|
|
127
|
+
|
|
128
|
+
### Query parms
|
|
129
|
+
|
|
130
|
+
A query parm is a column of `lb-url`. A control inside `lb-query="lb-url"`
|
|
131
|
+
that sends `lb-row-update` writes its value into the query string:
|
|
132
|
+
|
|
133
|
+
```html
|
|
134
|
+
<div lb-query="lb-url">
|
|
135
|
+
<select lb-column="team" lb-request="lb-row-update">
|
|
136
|
+
<option value="">Every team</option>
|
|
137
|
+
<option value="Engines">Engines</option>
|
|
138
|
+
</select>
|
|
139
|
+
</div>
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
On `change`, the hub sets that parm and keeps every other, and takes the
|
|
143
|
+
parm out when the value is empty. It replaces the current history entry, and
|
|
144
|
+
pushes one instead when the element carrying `lb-request` also carries
|
|
145
|
+
`lb-url-push`:
|
|
146
|
+
|
|
147
|
+
```html
|
|
148
|
+
<input lb-column="q" lb-request="lb-row-update" lb-url-push />
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
The hub answers the request itself, with no round trip, then reloads the
|
|
152
|
+
page's queries at the new URL. The page stays in place, and rows that come
|
|
153
|
+
back keep their place.
|
|
154
|
+
|
|
155
|
+
A control whose column the URL does not carry lands empty, so every control
|
|
156
|
+
inside `lb-query="lb-url"` shows what the address bar says, after a reload
|
|
157
|
+
and after Back alike.
|
|
158
|
+
|
|
159
|
+
The hub sends the query parms with every round trip, and the server hands
|
|
160
|
+
them to `contextFor`; see [the Express server](./server.md#database-layer).
|
|
161
|
+
A handler moves the URL by returning `url()`, when only the server knows the
|
|
162
|
+
new value; see [page files](./page-files.md#moving-the-url).
|
|
163
|
+
|
|
164
|
+
### An unknown page
|
|
165
|
+
|
|
166
|
+
A path that names no page shows the unknown-page dialog. Write it in the
|
|
167
|
+
chrome as a `<dialog>` carrying `lb-url-unknown`, and name `lb-url` on it to
|
|
168
|
+
show the path:
|
|
121
169
|
|
|
122
170
|
```html
|
|
123
|
-
<dialog lb-unknown
|
|
124
|
-
The URL <span lb-
|
|
171
|
+
<dialog lb-url-unknown lb-query="lb-url">
|
|
172
|
+
The URL <span lb-column="lb-path"></span> is not in this app.
|
|
125
173
|
</dialog>
|
|
126
174
|
```
|
|
127
175
|
|
|
128
|
-
|
|
129
|
-
|
|
176
|
+
When no page's stub matches the path, `lb-page-unknown` is `true`,
|
|
177
|
+
`lb-page-label` is null, `<main>` keeps the page it had, and the hub calls
|
|
178
|
+
`showModal()` on the dialog.
|
|
179
|
+
|
|
180
|
+
`@loadbare/widgets` ships this dialog as `<lb-unknown-page>`, for a chrome
|
|
181
|
+
that would rather write one tag; see
|
|
130
182
|
[The Basic Widget Library](./widgets.md#lb-unknown-page).
|
|
131
183
|
|
|
132
184
|
## Preventing the first-load blink
|
|
@@ -137,10 +189,9 @@ visible flash: the chrome appears first, then `<main>`'s real content pops in
|
|
|
137
189
|
a moment later and shifts everything around it.
|
|
138
190
|
|
|
139
191
|
`<body hidden>` avoids this by hiding the whole document, not just `<main>`,
|
|
140
|
-
until the hub has something to show. `<lb-hub>` un-hides `<body>` itself
|
|
141
|
-
first
|
|
142
|
-
|
|
143
|
-
intermediate state to flash.
|
|
192
|
+
until the hub has something to show. `<lb-hub>` un-hides `<body>` itself
|
|
193
|
+
once it has put the first page in `<main>`, so the chrome and the first
|
|
194
|
+
page's markup appear together, already in their final layout.
|
|
144
195
|
|
|
145
196
|
Hiding `<main>` alone doesn't work: an empty `<main>` already renders at zero
|
|
146
197
|
height, so hiding it changes nothing visible. The pop-in comes from the
|