@loadbare/app 0.4.0 → 0.5.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 (160) hide show
  1. package/README.md +53 -82
  2. package/dist/build/assemble.d.ts +7 -5
  3. package/dist/build/assemble.d.ts.map +1 -1
  4. package/dist/build/assemble.js +29 -9
  5. package/dist/build/cli.d.ts +20 -12
  6. package/dist/build/cli.d.ts.map +1 -1
  7. package/dist/build/cli.js +34 -16
  8. package/dist/build/elements.d.ts +15 -29
  9. package/dist/build/elements.d.ts.map +1 -1
  10. package/dist/build/elements.js +25 -111
  11. package/dist/build/expand.d.ts +1 -1
  12. package/dist/build/expand.js +1 -1
  13. package/dist/build/locations.d.ts +14 -37
  14. package/dist/build/locations.d.ts.map +1 -1
  15. package/dist/build/locations.js +24 -67
  16. package/dist/build/origins.d.ts +109 -0
  17. package/dist/build/origins.d.ts.map +1 -0
  18. package/dist/build/origins.js +270 -0
  19. package/dist/core/lb-constants.d.ts +1 -0
  20. package/dist/core/lb-constants.d.ts.map +1 -1
  21. package/dist/core/lb-constants.js +15 -8
  22. package/dist/core/lb-types.d.ts +2 -2
  23. package/dist/core/lb-types.d.ts.map +1 -1
  24. package/dist/hub/lb-apply.js +1 -1
  25. package/dist/hub/lb-hub.d.ts.map +1 -1
  26. package/dist/hub/lb-hub.js +44 -17
  27. package/dist/hub/lb-rows.js +3 -3
  28. package/dist/server/lb-server.d.ts +5 -4
  29. package/dist/server/lb-server.d.ts.map +1 -1
  30. package/dist/tests/assemble.test.js +11 -4
  31. package/dist/tests/elements.test.js +47 -51
  32. package/dist/tests/expand.test.d.ts +1 -1
  33. package/dist/tests/expand.test.js +2 -2
  34. package/dist/tests/fixtures/elements/collision/imports.d.ts +3 -0
  35. package/dist/tests/fixtures/elements/collision/imports.d.ts.map +1 -0
  36. package/dist/tests/fixtures/elements/collision/imports.js +1 -0
  37. package/dist/tests/fixtures/elements/manifest/imports.d.ts +3 -0
  38. package/dist/tests/fixtures/elements/manifest/imports.d.ts.map +1 -0
  39. package/dist/tests/fixtures/elements/manifest/imports.js +1 -0
  40. package/dist/tests/fixtures/elements/manifest-bad-entry/imports.d.ts +3 -0
  41. package/dist/tests/fixtures/elements/manifest-bad-entry/imports.d.ts.map +1 -0
  42. package/dist/tests/fixtures/elements/manifest-bad-entry/imports.js +1 -0
  43. package/dist/tests/fixtures/elements/{collision/elements.d.ts → manifest-not-array/imports.d.ts} +1 -1
  44. package/dist/tests/fixtures/elements/manifest-not-array/imports.d.ts.map +1 -0
  45. package/dist/tests/fixtures/elements/manifest-not-array/imports.js +1 -0
  46. package/dist/tests/fixtures/elements/pkg/acme-widget.d.ts +2 -0
  47. package/dist/tests/fixtures/elements/pkg/acme-widget.d.ts.map +1 -0
  48. package/dist/tests/fixtures/elements/pkg/acme-widget.js +1 -0
  49. package/dist/tests/lb-express.test.js +1 -1
  50. package/dist/tests/origins.test.d.ts +10 -0
  51. package/dist/tests/origins.test.d.ts.map +1 -0
  52. package/dist/tests/origins.test.js +326 -0
  53. package/dist/tests/pages.test.js +3 -3
  54. package/dist/tests/styles.test.js +7 -4
  55. package/docs/reference/builder.md +128 -0
  56. package/docs/reference/chrome.md +75 -0
  57. package/docs/reference/css.md +44 -0
  58. package/docs/reference/custom-elements.md +327 -0
  59. package/docs/reference/data-binding.md +240 -0
  60. package/docs/reference/overview.md +38 -0
  61. package/docs/reference/page-files.md +175 -0
  62. package/docs/reference/server.md +123 -0
  63. package/docs/reference/widgets.md +163 -0
  64. package/docs/roadmap.md +130 -0
  65. package/docs/testing.md +228 -0
  66. package/docs/theory.md +344 -223
  67. package/docs/tutorials/000-getting-started.md +86 -0
  68. package/docs/tutorials/010-pages-and-navigation.md +129 -0
  69. package/docs/tutorials/020-css.md +103 -0
  70. package/docs/tutorials/030-html-decomposition.md +79 -0
  71. package/docs/tutorials/040-displaying-data.md +169 -0
  72. package/docs/tutorials/050-actions.md +77 -0
  73. package/docs/tutorials/060-custom-element-code.md +73 -0
  74. package/docs/tutorials/065-conditional-rendering.md +161 -0
  75. package/docs/tutorials/070-displaying-a-list.md +137 -0
  76. package/docs/tutorials/072-inserting-into-a-list.md +88 -0
  77. package/docs/tutorials/074-deleting-from-a-list.md +77 -0
  78. package/docs/tutorials/076-updating-a-list-item.md +86 -0
  79. package/docs/tutorials/080-widget-requests.md +124 -0
  80. package/docs/tutorials/090-using-widget-libraries.md +75 -0
  81. package/package.json +4 -12
  82. package/dist/client.js +0 -522
  83. package/dist/demo-static/src/widgets/app-box.d.ts +0 -15
  84. package/dist/demo-static/src/widgets/app-box.d.ts.map +0 -1
  85. package/dist/demo-static/src/widgets/app-box.js +0 -19
  86. package/dist/tests/fixtures/elements/collision/elements.d.ts.map +0 -1
  87. package/dist/tests/fixtures/elements/collision/elements.js +0 -3
  88. package/dist/tests/fixtures/elements/manifest/elements.d.ts +0 -5
  89. package/dist/tests/fixtures/elements/manifest/elements.d.ts.map +0 -1
  90. package/dist/tests/fixtures/elements/manifest/elements.js +0 -3
  91. package/dist/tests/fixtures/elements/manifest-bad-tag/elements.d.ts +0 -5
  92. package/dist/tests/fixtures/elements/manifest-bad-tag/elements.d.ts.map +0 -1
  93. package/dist/tests/fixtures/elements/manifest-bad-tag/elements.js +0 -3
  94. package/dist/tests/fixtures/elements/manifest-bad-value/elements.d.ts +0 -5
  95. package/dist/tests/fixtures/elements/manifest-bad-value/elements.d.ts.map +0 -1
  96. package/dist/tests/fixtures/elements/manifest-bad-value/elements.js +0 -3
  97. package/dist/tests/golden.test.d.ts +0 -19
  98. package/dist/tests/golden.test.d.ts.map +0 -1
  99. package/dist/tests/golden.test.js +0 -60
  100. package/dist/tests/helpers/window.d.ts +0 -43
  101. package/dist/tests/helpers/window.d.ts.map +0 -1
  102. package/dist/tests/helpers/window.js +0 -78
  103. package/dist/tests/lb-input.test.d.ts +0 -9
  104. package/dist/tests/lb-input.test.d.ts.map +0 -1
  105. package/dist/tests/lb-input.test.js +0 -78
  106. package/dist/tests/lb-list.test.d.ts +0 -12
  107. package/dist/tests/lb-list.test.d.ts.map +0 -1
  108. package/dist/tests/lb-list.test.js +0 -44
  109. package/dist/tests/lb-options.test.d.ts +0 -10
  110. package/dist/tests/lb-options.test.d.ts.map +0 -1
  111. package/dist/tests/lb-options.test.js +0 -121
  112. package/dist/tests/lb-picker.test.d.ts +0 -14
  113. package/dist/tests/lb-picker.test.d.ts.map +0 -1
  114. package/dist/tests/lb-picker.test.js +0 -59
  115. package/dist/tests/lb-select.test.d.ts +0 -9
  116. package/dist/tests/lb-select.test.d.ts.map +0 -1
  117. package/dist/tests/lb-select.test.js +0 -71
  118. package/dist/tests/lb-table.test.d.ts +0 -15
  119. package/dist/tests/lb-table.test.d.ts.map +0 -1
  120. package/dist/tests/lb-table.test.js +0 -205
  121. package/dist/widgets/index.d.ts +0 -7
  122. package/dist/widgets/index.d.ts.map +0 -1
  123. package/dist/widgets/index.js +0 -6
  124. package/dist/widgets/lb-input.d.ts +0 -2
  125. package/dist/widgets/lb-input.d.ts.map +0 -1
  126. package/dist/widgets/lb-input.js +0 -48
  127. package/dist/widgets/lb-list.d.ts +0 -2
  128. package/dist/widgets/lb-list.d.ts.map +0 -1
  129. package/dist/widgets/lb-list.js +0 -17
  130. package/dist/widgets/lb-options.d.ts +0 -26
  131. package/dist/widgets/lb-options.d.ts.map +0 -1
  132. package/dist/widgets/lb-options.js +0 -72
  133. package/dist/widgets/lb-picker.d.ts +0 -2
  134. package/dist/widgets/lb-picker.d.ts.map +0 -1
  135. package/dist/widgets/lb-picker.js +0 -25
  136. package/dist/widgets/lb-select.d.ts +0 -2
  137. package/dist/widgets/lb-select.d.ts.map +0 -1
  138. package/dist/widgets/lb-select.js +0 -43
  139. package/dist/widgets/lb-table.d.ts +0 -2
  140. package/dist/widgets/lb-table.d.ts.map +0 -1
  141. package/dist/widgets/lb-table.js +0 -113
  142. package/docs/application-chrome.md +0 -36
  143. package/docs/building-html-pages.md +0 -130
  144. package/docs/getting-started.md +0 -120
  145. package/docs/guide.md +0 -1164
  146. package/docs/hosting.md +0 -218
  147. package/docs/latent-risks.md +0 -20
  148. package/widgets/index.ts +0 -6
  149. package/widgets/lb-input.html +0 -1
  150. package/widgets/lb-input.ts +0 -64
  151. package/widgets/lb-list.html +0 -1
  152. package/widgets/lb-list.ts +0 -21
  153. package/widgets/lb-options.html +0 -4
  154. package/widgets/lb-options.ts +0 -88
  155. package/widgets/lb-picker.html +0 -7
  156. package/widgets/lb-picker.ts +0 -27
  157. package/widgets/lb-select.html +0 -4
  158. package/widgets/lb-select.ts +0 -55
  159. package/widgets/lb-table.html +0 -8
  160. package/widgets/lb-table.ts +0 -126
@@ -1,36 +0,0 @@
1
- # Application Chrome
2
-
3
- The application Chrome - banner, nav, main and footer, is static HTML.
4
-
5
- It is found by name, not by location: it can be placed anywhere in the tree
6
- the builder scans, as any file ending `.chrome.html` — there must be exactly
7
- one. By convention we name it `src/chrome.chrome.html`.
8
-
9
- In our docs we consider chrome to be invariant across pages. This is
10
- not a strict technical requirement, as loadbare can update anything,
11
- but we do not provide examples or tests of dynamic chrome.
12
-
13
- The minimum requirements for the chrome file are:
14
-
15
- - the `<lb-hub>` element as first element below `<body>`
16
- - an empty `<main></main>` element. Its content is populated by
17
- the hub from the application pages.
18
-
19
- ```html
20
- <!doctype html>
21
- <html lang="en">
22
- <head>
23
- <meta charset="utf-8" />
24
- <title><!-- content goes here --></title>
25
- <script src="/client.js" defer></script>
26
- </head>
27
- <body>
28
- <lb-hub>
29
- <header><!-- content goes here --></header>
30
- <nav><!-- content goes here --></nav>
31
- <main></main>
32
- <footer><!-- content goes here --></footer>
33
- </lb-hub>
34
- </body>
35
- </html>
36
- ```
@@ -1,130 +0,0 @@
1
- # Building HTML Pages
2
-
3
- A page is authored as one HTML file. It may contain widget tags. Expansion
4
- turns each one that has a definition into the tree that definition stands
5
- for. Expansion runs at build time, before there is a request, and before
6
- there is any data.
7
-
8
- `LB-*` is the framework's reserved namespace — Loadbare App's own widgets, and
9
- the convention its docs use. An application's own widgets should use their
10
- own prefix instead (`app-nav`, not `lb-nav`); a tag outside the `LB-*`
11
- namespace expands exactly the same way when it has a definition, but is not
12
- required to have one — with none, it is assumed to be a plain custom element,
13
- registered by script alone (see build/elements.ts).
14
-
15
- ## Definitions
16
-
17
- A definition is one HTML file per tag. The file name gives the tag:
18
- `lb-options.html` defines `LB-OPTIONS`; `app-nav.html` defines `APP-NAV`.
19
-
20
- Loadbare App's own widgets live in this package's own `widgets/`, read by
21
- `loadDefinitions(dirs)`, which takes a list of directories in order — a later
22
- one overrides an earlier one for the same tag name. An application's own
23
- definitions are not confined to a directory at all: they are found by
24
- filename anywhere in its source tree (see `docs/getting-started.md`) and
25
- overlaid on the built-in set with `addDefinitions`, the same override an
26
- application directory would give a built-in widget.
27
-
28
- The full set of definitions is checked for a cycle in which definitions
29
- reference each other by tag, and throws if one exists.
30
-
31
- ## Expanding a page
32
-
33
- `expand(source, defs)` walks the authored tree and replaces every widget tag
34
- that has a matching entry in `defs` with the tree that entry produces. A tag
35
- in the `LB-*` namespace is required to have one — an unresolved tag there
36
- throws. Outside that namespace, a tag with no definition is left exactly as
37
- authored.
38
-
39
- A definition may itself use other widget tags. Expansion resolves those the
40
- same way, as deep as the definitions go.
41
-
42
- ## Parameters
43
-
44
- A definition may declare a placeholder, written `{{name}}`, as the entire
45
- value of an attribute or the entire text of a text node.
46
-
47
- An authored tag supplies a placeholder's value with an attribute named
48
- `exp-<name>`. `exp-label="Member:"` supplies `{{label}}`.
49
-
50
- HTML lowercases attribute names, so a placeholder name may not contain an
51
- uppercase letter — `loadDefinitions` rejects a definition that declares one.
52
-
53
- Supplying `exp-x` on a tag whose definition has no `{{x}}` is an error.
54
-
55
- If a placeholder has no value supplied, the attribute it fills is dropped
56
- rather than emitted empty; a text placeholder becomes empty text.
57
-
58
- ## The slot
59
-
60
- A definition may mark one element `lb-slot`. The authored tag's child nodes
61
- move into that element, replacing it. A definition with no `lb-slot` rejects
62
- any non-whitespace content written inside the authored tag.
63
-
64
- ## Named template destinations
65
-
66
- A definition may mark more than one element `lb-template="<name>"`, each a
67
- destination. An authored tag supplies content for a destination by writing a
68
- `<template lb-template="<name>">` among its children; expansion moves the
69
- template's content into the destination and discards the wrapping `<template>`
70
- tag. A destination with no matching template is left as the definition wrote
71
- it.
72
-
73
- Two templates naming the same destination, or a template naming a destination
74
- the definition does not declare, is an error.
75
-
76
- A definition applies named destinations before the slot: content addressed to
77
- a destination by name does not also count as slot content.
78
-
79
- ### Example
80
-
81
- `widgets/lb-table.html`:
82
-
83
- ```html
84
- <table>
85
- <caption>
86
- {{caption}}
87
- </caption>
88
- <thead lb-template="head"></thead>
89
- <tbody lb-slot></tbody>
90
- <tfoot lb-template="foot"></tfoot>
91
- </table>
92
- ```
93
-
94
- Authored in a page:
95
-
96
- ```html
97
- <lb-table exp-caption="Everyone, by team">
98
- <template lb-template="head">
99
- <tr>
100
- <th>Name</th>
101
- <th>Role</th>
102
- </tr>
103
- </template>
104
- <tr>
105
- <td>Row content for the slot</td>
106
- </tr>
107
- </lb-table>
108
- ```
109
-
110
- The `head` template's content becomes the `<thead>`'s children. The `<tr>`
111
- written outside any `<template>` is slot content and becomes a child of
112
- `<tbody>`. There is no template addressed to `foot`, so the `<tfoot>` ships
113
- empty, exactly as the definition wrote it.
114
-
115
- ## Template content elsewhere on the page
116
-
117
- Expansion also descends into the content of any `<template>` on the page,
118
- including one with no `lb-template` attribute — for example a row template
119
- consumed by a widget at runtime rather than by expansion. A placeholder or
120
- widget tag written inside such a template is still expanded.
121
-
122
- ## Output
123
-
124
- `expand(source, defs)` returns HTML text. Substitution is applied to a parsed
125
- tree through DOM APIs — `setAttribute`, text node values — never to a string,
126
- so a value supplied through `exp-*` cannot be reparsed as markup.
127
-
128
- What `expand` returns is what ships. No value from a request or a database is
129
- added after expansion; those values land on the already-expanded tree later,
130
- as attributes.
@@ -1,120 +0,0 @@
1
- # Getting Started
2
-
3
- We begin with the smallest working application. This app does not even
4
- have any pages, but it will load without error, and is inspectable.
5
-
6
- ## The chrome file
7
-
8
- Write a file ending `.chrome.html` — say, `src/chrome.chrome.html`. There
9
- must be exactly one of these anywhere under `src/`; the builder finds it by
10
- that name, not by which directory it's in.
11
-
12
- At minimum, the chrome must contain:
13
-
14
- - a link to the `client.js` script
15
- - The `<lb-hub>` element just inside `<body>`
16
- - an empty `<main>` inside `<lb-hub>`
17
-
18
- ```html
19
- <!doctype html>
20
- <html lang="en">
21
- <head>
22
- <meta charset="utf-8" />
23
- <title>Getting Started</title>
24
- <script src="/client.js" defer></script>
25
- </head>
26
- <body>
27
- <lb-hub>
28
- <main></main>
29
- </lb-hub>
30
- </body>
31
- </html>
32
- ```
33
-
34
- The client script is generated by the builder, and contains some core code
35
- and the Javascript
36
- for all custom elements in the app. Since we have only `lb-hub`, the build
37
- will produce a `client.js` containing the core code and only the class for `lb-hub`.
38
-
39
- ## Serving It
40
-
41
- Create `server.js` as an express server:
42
-
43
- ```js
44
- import express from "express";
45
- import { readFileSync } from "node:fs";
46
-
47
- const app = express();
48
-
49
- app.get("/", (_req, res) =>
50
- res.type("html").send(readFileSync("dist/app.html", "utf-8")),
51
- );
52
- app.use("/client.js", express.static("dist/client.js"));
53
-
54
- app.listen(8787);
55
- ```
56
-
57
- `dist/app.html` is read on every request rather than once at startup, so a
58
- rebuild in watch mode is visible without restarting the server.
59
-
60
- ## The dev Script
61
-
62
- Add to package.json:
63
-
64
- ```json
65
- {
66
- "scripts": {
67
- "dev": "loadbare-app-build --watch & node server.js"
68
- }
69
- }
70
- ```
71
-
72
- `loadbare-app-build` scans `src/` by default; `--src` overrides which tree. It
73
- takes no other location flags — everything under that tree is found by what
74
- a file is named, not by which directory holds it:
75
-
76
- - `*.chrome.html` — the one chrome file
77
- - `*.page.html` — a page, named for the part before the suffix
78
- - any other `.html` — a widget definition, named for its own filename
79
- - a `.ts` file shaped like a custom element tag (e.g. `lb-nav.ts`,
80
- `app-box.ts`) — a widget's script
81
- - `*.hooks.ts` / `*.queries.ts` — a page's server half, paired with a
82
- `*.page.html` by sharing its basename
83
- - `.css` — a stylesheet, concatenated with every other one found
84
- - `elements.ts` — third-party custom elements: a default export mapping tag
85
- to import specifier, e.g. `{ "acme-date-picker": "@acme/date-picker" }`
86
-
87
- A widget's markup and script don't need to sit in the same place, or in any
88
- particular directory at all — `src/pages/home.page.html` and
89
- `src/lb-nav.html` are both found the same way `src/widgets/lb-nav.html`
90
- would be.
91
-
92
- ## CSS
93
-
94
- Every `.css` file anywhere under `src/` is concatenated into `dist/app.css`,
95
- in one order: sorted by filename, not by directory. Put a stylesheet next to
96
- the markup it styles, wherever that is convenient — a global one sorts to
97
- the front on its own by naming itself `00-reset.css` or `aa-globals.css`,
98
- regardless of which directory it lives in. Nothing here knows about widgets
99
- or pages; it is exactly the concatenation of what was authored, with no
100
- scoping and no plain `style="..."` attribute anywhere the framework writes
101
- markup, since that is inline code the same way `<script>` is, and Loadbare App
102
- targets a CSP that refuses both.
103
-
104
- The chrome links it like any other asset — `<link rel="stylesheet"
105
- href="/app.css" />` — the builder never writes into the chrome itself.
106
-
107
- This script runs the Loadbare App builder in watch mode, alongside the server.
108
- With `--watch`, every `.html`, `.ts` and `.css` file under `src/` is watched —
109
- a page, a widget's markup, a widget's class, a stylesheet, and `elements.ts`
110
- all feed the build.
111
-
112
- Loadbare App does not reload the browser on a rebuild. Watch mode keeps
113
- `dist/app.html`, `dist/client.js` and `dist/app.css` current on disk; the
114
- browser picks up a change on the next manual refresh.
115
-
116
- ## Run it
117
-
118
- Try `npm run dev`, and navigate the browser to localhost:8787, you
119
- should see an empty page, with a console message, and the view source
120
- option should show exactly our page.