@loadbare/app 0.4.0 → 0.5.1
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 +53 -82
- package/dist/build/assemble.d.ts +7 -5
- package/dist/build/assemble.d.ts.map +1 -1
- package/dist/build/assemble.js +29 -9
- package/dist/build/cli.d.ts +20 -12
- package/dist/build/cli.d.ts.map +1 -1
- package/dist/build/cli.js +34 -16
- package/dist/build/elements.d.ts +15 -29
- package/dist/build/elements.d.ts.map +1 -1
- package/dist/build/elements.js +25 -111
- package/dist/build/expand.d.ts +1 -1
- package/dist/build/expand.js +1 -1
- package/dist/build/format.d.ts +6 -3
- package/dist/build/format.d.ts.map +1 -1
- package/dist/build/format.js +6 -3
- package/dist/build/locations.d.ts +14 -37
- package/dist/build/locations.d.ts.map +1 -1
- package/dist/build/locations.js +31 -69
- package/dist/build/origins.d.ts +109 -0
- package/dist/build/origins.d.ts.map +1 -0
- package/dist/build/origins.js +270 -0
- package/dist/core/lb-constants.d.ts +1 -0
- package/dist/core/lb-constants.d.ts.map +1 -1
- package/dist/core/lb-constants.js +15 -8
- package/dist/core/lb-types.d.ts +2 -2
- package/dist/core/lb-types.d.ts.map +1 -1
- package/dist/hub/lb-apply.js +1 -1
- package/dist/hub/lb-hub.d.ts.map +1 -1
- package/dist/hub/lb-hub.js +44 -17
- package/dist/hub/lb-rows.d.ts.map +1 -1
- package/dist/hub/lb-rows.js +3 -3
- package/dist/server/lb-express.d.ts.map +1 -1
- package/dist/server/lb-server.d.ts +5 -4
- package/dist/server/lb-server.d.ts.map +1 -1
- package/dist/tests/assemble.test.js +11 -4
- package/dist/tests/elements.test.js +47 -51
- package/dist/tests/expand.test.d.ts +1 -1
- package/dist/tests/expand.test.js +2 -2
- package/dist/tests/fixtures/elements/collision/imports.d.ts +3 -0
- package/dist/tests/fixtures/elements/collision/imports.d.ts.map +1 -0
- package/dist/tests/fixtures/elements/collision/imports.js +1 -0
- package/dist/tests/fixtures/elements/manifest/imports.d.ts +3 -0
- package/dist/tests/fixtures/elements/manifest/imports.d.ts.map +1 -0
- package/dist/tests/fixtures/elements/manifest/imports.js +1 -0
- package/dist/tests/fixtures/elements/manifest-bad-entry/imports.d.ts +3 -0
- package/dist/tests/fixtures/elements/manifest-bad-entry/imports.d.ts.map +1 -0
- package/dist/tests/fixtures/elements/manifest-bad-entry/imports.js +1 -0
- package/dist/tests/fixtures/elements/{collision/elements.d.ts → manifest-not-array/imports.d.ts} +1 -1
- package/dist/tests/fixtures/elements/manifest-not-array/imports.d.ts.map +1 -0
- package/dist/tests/fixtures/elements/manifest-not-array/imports.js +1 -0
- package/dist/tests/fixtures/elements/pkg/acme-widget.d.ts +2 -0
- package/dist/tests/fixtures/elements/pkg/acme-widget.d.ts.map +1 -0
- package/dist/tests/fixtures/elements/pkg/acme-widget.js +1 -0
- package/dist/tests/lb-express.test.js +1 -1
- package/dist/tests/origins.test.d.ts +10 -0
- package/dist/tests/origins.test.d.ts.map +1 -0
- package/dist/tests/origins.test.js +326 -0
- package/dist/tests/pages.test.js +3 -3
- package/dist/tests/styles.test.js +7 -4
- package/docs/reference/builder.md +128 -0
- package/docs/reference/chrome.md +75 -0
- package/docs/reference/css.md +44 -0
- package/docs/reference/custom-elements.md +327 -0
- package/docs/reference/data-binding.md +240 -0
- package/docs/reference/overview.md +38 -0
- package/docs/reference/page-files.md +175 -0
- package/docs/reference/server.md +123 -0
- package/docs/reference/widgets.md +163 -0
- package/docs/roadmap.md +130 -0
- package/docs/testing.md +228 -0
- package/docs/theory.md +344 -223
- package/docs/tutorials/000-getting-started.md +86 -0
- package/docs/tutorials/010-pages-and-navigation.md +129 -0
- package/docs/tutorials/020-css.md +103 -0
- package/docs/tutorials/030-html-decomposition.md +79 -0
- package/docs/tutorials/040-displaying-data.md +169 -0
- package/docs/tutorials/050-actions.md +77 -0
- package/docs/tutorials/060-custom-element-code.md +73 -0
- package/docs/tutorials/065-conditional-rendering.md +161 -0
- package/docs/tutorials/070-displaying-a-list.md +137 -0
- package/docs/tutorials/072-inserting-into-a-list.md +88 -0
- package/docs/tutorials/074-deleting-from-a-list.md +77 -0
- package/docs/tutorials/076-updating-a-list-item.md +86 -0
- package/docs/tutorials/080-widget-requests.md +124 -0
- package/docs/tutorials/090-using-widget-libraries.md +75 -0
- package/package.json +10 -18
- package/dist/client.js +0 -522
- package/dist/demo-static/src/widgets/app-box.d.ts +0 -15
- package/dist/demo-static/src/widgets/app-box.d.ts.map +0 -1
- package/dist/demo-static/src/widgets/app-box.js +0 -19
- package/dist/tests/fixtures/elements/collision/elements.d.ts.map +0 -1
- package/dist/tests/fixtures/elements/collision/elements.js +0 -3
- package/dist/tests/fixtures/elements/manifest/elements.d.ts +0 -5
- package/dist/tests/fixtures/elements/manifest/elements.d.ts.map +0 -1
- package/dist/tests/fixtures/elements/manifest/elements.js +0 -3
- package/dist/tests/fixtures/elements/manifest-bad-tag/elements.d.ts +0 -5
- package/dist/tests/fixtures/elements/manifest-bad-tag/elements.d.ts.map +0 -1
- package/dist/tests/fixtures/elements/manifest-bad-tag/elements.js +0 -3
- package/dist/tests/fixtures/elements/manifest-bad-value/elements.d.ts +0 -5
- package/dist/tests/fixtures/elements/manifest-bad-value/elements.d.ts.map +0 -1
- package/dist/tests/fixtures/elements/manifest-bad-value/elements.js +0 -3
- package/dist/tests/golden.test.d.ts +0 -19
- package/dist/tests/golden.test.d.ts.map +0 -1
- package/dist/tests/golden.test.js +0 -60
- package/dist/tests/helpers/window.d.ts +0 -43
- package/dist/tests/helpers/window.d.ts.map +0 -1
- package/dist/tests/helpers/window.js +0 -78
- package/dist/tests/lb-input.test.d.ts +0 -9
- package/dist/tests/lb-input.test.d.ts.map +0 -1
- package/dist/tests/lb-input.test.js +0 -78
- package/dist/tests/lb-list.test.d.ts +0 -12
- package/dist/tests/lb-list.test.d.ts.map +0 -1
- package/dist/tests/lb-list.test.js +0 -44
- package/dist/tests/lb-options.test.d.ts +0 -10
- package/dist/tests/lb-options.test.d.ts.map +0 -1
- package/dist/tests/lb-options.test.js +0 -121
- package/dist/tests/lb-picker.test.d.ts +0 -14
- package/dist/tests/lb-picker.test.d.ts.map +0 -1
- package/dist/tests/lb-picker.test.js +0 -59
- package/dist/tests/lb-select.test.d.ts +0 -9
- package/dist/tests/lb-select.test.d.ts.map +0 -1
- package/dist/tests/lb-select.test.js +0 -71
- package/dist/tests/lb-table.test.d.ts +0 -15
- package/dist/tests/lb-table.test.d.ts.map +0 -1
- package/dist/tests/lb-table.test.js +0 -205
- package/dist/widgets/index.d.ts +0 -7
- package/dist/widgets/index.d.ts.map +0 -1
- package/dist/widgets/index.js +0 -6
- package/dist/widgets/lb-input.d.ts +0 -2
- package/dist/widgets/lb-input.d.ts.map +0 -1
- package/dist/widgets/lb-input.js +0 -48
- package/dist/widgets/lb-list.d.ts +0 -2
- package/dist/widgets/lb-list.d.ts.map +0 -1
- package/dist/widgets/lb-list.js +0 -17
- package/dist/widgets/lb-options.d.ts +0 -26
- package/dist/widgets/lb-options.d.ts.map +0 -1
- package/dist/widgets/lb-options.js +0 -72
- package/dist/widgets/lb-picker.d.ts +0 -2
- package/dist/widgets/lb-picker.d.ts.map +0 -1
- package/dist/widgets/lb-picker.js +0 -25
- package/dist/widgets/lb-select.d.ts +0 -2
- package/dist/widgets/lb-select.d.ts.map +0 -1
- package/dist/widgets/lb-select.js +0 -43
- package/dist/widgets/lb-table.d.ts +0 -2
- package/dist/widgets/lb-table.d.ts.map +0 -1
- package/dist/widgets/lb-table.js +0 -113
- package/docs/application-chrome.md +0 -36
- package/docs/building-html-pages.md +0 -130
- package/docs/getting-started.md +0 -120
- package/docs/guide.md +0 -1164
- package/docs/hosting.md +0 -218
- package/docs/latent-risks.md +0 -20
- package/widgets/index.ts +0 -6
- package/widgets/lb-input.html +0 -1
- package/widgets/lb-input.ts +0 -64
- package/widgets/lb-list.html +0 -1
- package/widgets/lb-list.ts +0 -21
- package/widgets/lb-options.html +0 -4
- package/widgets/lb-options.ts +0 -88
- package/widgets/lb-picker.html +0 -7
- package/widgets/lb-picker.ts +0 -27
- package/widgets/lb-select.html +0 -4
- package/widgets/lb-select.ts +0 -55
- package/widgets/lb-table.html +0 -8
- package/widgets/lb-table.ts +0 -126
package/README.md
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
# Loadbare App
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
The fundamentals of @loadbare/app are fixed, we are now working
|
|
4
|
+
on completeness.
|
|
5
|
+
|
|
6
|
+
> This package is being prepped for 1.0, current work is:
|
|
7
|
+
> 1. docs (nearly done)
|
|
8
|
+
> 2. demos (must be normalized and checked against docs)
|
|
9
|
+
> 3. test a release/use cycle, make sure all instructions work
|
|
10
|
+
|
|
6
11
|
|
|
7
12
|
## Purpose
|
|
8
13
|
|
|
@@ -14,82 +19,48 @@ Loadbare App has two twin primary goals
|
|
|
14
19
|
to near zero, so the app developer is spending maximum time on the app
|
|
15
20
|
instead of the tooling.
|
|
16
21
|
- To give the developer a fighting chance to provide complete server round
|
|
17
|
-
trips, from request to final paint, in 300ms or less
|
|
18
|
-
|
|
19
|
-
##
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
##
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
Nothing here is about protecting the HTML, which is visible in the developer
|
|
63
|
-
tools regardless. It is about the technology being open to inspection by
|
|
64
|
-
whoever wants to look.
|
|
65
|
-
|
|
66
|
-
## Documentation
|
|
67
|
-
|
|
68
|
-
[`docs/theory.md`](./docs/theory.md) states what Loadbare App is and
|
|
69
|
-
why. It is authoritative; where any other document disagrees with it, the other
|
|
70
|
-
document is wrong.
|
|
71
|
-
|
|
72
|
-
- [Programmer's Guide](./docs/guide.md) — how to build an application with
|
|
73
|
-
Loadbare App. Each section is marked with whether the code does it yet.
|
|
74
|
-
- [Hosting a Loadbare App Application](./docs/hosting.md) — registering pages,
|
|
75
|
-
assembling the shell, navigation, and serving the two endpoints from
|
|
76
|
-
Express. Everything you do once per application rather than once per page.
|
|
77
|
-
- [Theory of Loadbare App](./docs/theory.md) — scope, the performance budget,
|
|
78
|
-
the thesis, and what is settled so far.
|
|
79
|
-
- [Communication channels](./docs-llm-slop/communication-channels.md) — what
|
|
80
|
-
the host/data split means on the wire.
|
|
81
|
-
- [Data binding](./docs-llm-slop/data-binding.md) — the addressing vocabulary
|
|
82
|
-
and how a data fragment lands on a widget.
|
|
83
|
-
- [Requests](./docs-llm-slop/requests.md) — how a widget reaches the server,
|
|
84
|
-
and what the server may trust.
|
|
85
|
-
- [Bundling](./docs-llm-slop/bundling.md) — how the static half is packaged
|
|
86
|
-
and shipped.
|
|
87
|
-
- [Expansion](./docs-llm-slop/expansion.md) — how one authored tag becomes the
|
|
88
|
-
tree it stands for, and why the definition language has no control flow.
|
|
89
|
-
- [Coming from other frameworks](./docs-llm-slop/coming-from-other-frameworks.md)
|
|
90
|
-
— what changes if you already know React, Angular, htmx or Datastar.
|
|
91
|
-
- [Prior art](./docs-llm-slop/prior-art.md) — what has been done before, and
|
|
92
|
-
why nothing was adopted off the shelf.
|
|
93
|
-
|
|
94
|
-
The guide states the API as it should be and marks each section with whether
|
|
95
|
-
the code does it yet. Where the two disagree, the code is what moves.
|
|
22
|
+
trips, from request to final paint, in 300ms or less.
|
|
23
|
+
|
|
24
|
+
## Widgets
|
|
25
|
+
|
|
26
|
+
This package ships one custom element, `<lb-hub>`. The widgets an application
|
|
27
|
+
displays data with — `lb-input`, `lb-select`, `lb-list`, `lb-options`,
|
|
28
|
+
`lb-table`, `lb-picker` — ship separately, in
|
|
29
|
+
[@loadbare/widgets](../widgets/README.md):
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
npm install @loadbare/app @loadbare/widgets
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
// src/imports.ts
|
|
37
|
+
export default ["@loadbare/widgets"];
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The builder resolves that package the way it resolves anyone else's, so a
|
|
41
|
+
widget library written by a third party, or by the application's own team,
|
|
42
|
+
arrives through the same one line. See
|
|
43
|
+
[The Basic Widget Library](./docs/reference/widgets.md) for what each widget
|
|
44
|
+
binds and sends, and
|
|
45
|
+
[Using Widget Libraries](./docs/tutorials/090-using-widget-libraries.md) for
|
|
46
|
+
what listing a package does.
|
|
47
|
+
|
|
48
|
+
## Tutorials
|
|
49
|
+
|
|
50
|
+
[Getting Started](./docs/tutorials/000-getting-started.md): a step-by-step
|
|
51
|
+
guide to building a database app, introducing one new concept in
|
|
52
|
+
each lesson.
|
|
53
|
+
|
|
54
|
+
## Reference
|
|
55
|
+
|
|
56
|
+
[The Elements of a Loadbare Application](./docs/reference/overview.md)
|
|
57
|
+
|
|
58
|
+
## Theory
|
|
59
|
+
|
|
60
|
+
[Theory](./docs/theory.md): the design rationale behind Loadbare App.
|
|
61
|
+
|
|
62
|
+
## Roadmap Items for 1.0 and 1.1
|
|
63
|
+
|
|
64
|
+
[Roadmap](./docs/roadmap.md)
|
|
65
|
+
|
|
66
|
+
|
package/dist/build/assemble.d.ts
CHANGED
|
@@ -9,23 +9,25 @@
|
|
|
9
9
|
* expanded host is wrapped in `<template id="page-<name>">` and, together
|
|
10
10
|
* with the chrome's own expanded body content, spliced back into the
|
|
11
11
|
* chrome's `<body>`. The result is the one document a server has to serve
|
|
12
|
-
* for every route — see docs/getting-started.md and
|
|
12
|
+
* for every route — see docs/tutorials/000-getting-started.md and
|
|
13
|
+
* docs/reference/builder.md.
|
|
13
14
|
*
|
|
14
15
|
* Every path here is a parameter, resolved once by build/locations.ts — this
|
|
15
16
|
* module never reconstructs one of its own, and never reads a directory
|
|
16
17
|
* looking for pages or widgets; it is handed exactly which files those are.
|
|
17
18
|
*/
|
|
18
|
-
import type { PageFile
|
|
19
|
+
import type { PageFile } from "./locations.js";
|
|
20
|
+
import type { OriginScan } from "./origins.js";
|
|
19
21
|
export interface AssembleOptions {
|
|
20
22
|
chromeFile: string;
|
|
21
23
|
pages: PageFile[];
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
/** Every origin, already scanned, in cascade order — see build/origins.ts. */
|
|
25
|
+
scans: OriginScan[];
|
|
24
26
|
}
|
|
25
27
|
export interface Assembled {
|
|
26
28
|
html: string;
|
|
27
29
|
/** Every custom element tag left in the document once expansion is done. */
|
|
28
30
|
usedTags: Set<string>;
|
|
29
31
|
}
|
|
30
|
-
export declare function assemble({ chromeFile, pages,
|
|
32
|
+
export declare function assemble({ chromeFile, pages, scans, }: AssembleOptions): Promise<Assembled>;
|
|
31
33
|
//# sourceMappingURL=assemble.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assemble.d.ts","sourceRoot":"","sources":["../../build/assemble.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"assemble.d.ts","sourceRoot":"","sources":["../../build/assemble.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAeH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAuB/C,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,8EAA8E;IAC9E,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACvB;AAED,wBAAsB,QAAQ,CAAC,EAC7B,UAAU,EACV,KAAK,EACL,KAAK,GACN,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,CAAC,CA2CtC"}
|
package/dist/build/assemble.js
CHANGED
|
@@ -9,23 +9,42 @@
|
|
|
9
9
|
* expanded host is wrapped in `<template id="page-<name>">` and, together
|
|
10
10
|
* with the chrome's own expanded body content, spliced back into the
|
|
11
11
|
* chrome's `<body>`. The result is the one document a server has to serve
|
|
12
|
-
* for every route — see docs/getting-started.md and
|
|
12
|
+
* for every route — see docs/tutorials/000-getting-started.md and
|
|
13
|
+
* docs/reference/builder.md.
|
|
13
14
|
*
|
|
14
15
|
* Every path here is a parameter, resolved once by build/locations.ts — this
|
|
15
16
|
* module never reconstructs one of its own, and never reads a directory
|
|
16
17
|
* looking for pages or widgets; it is handed exactly which files those are.
|
|
17
18
|
*/
|
|
18
19
|
import { readFile } from "node:fs/promises";
|
|
19
|
-
import {
|
|
20
|
+
import { JSDOM } from "jsdom";
|
|
21
|
+
import { addDefinitions, customElementTags, expand, } from "./expand.js";
|
|
20
22
|
import { formatHtml } from "./format.js";
|
|
21
|
-
import { PAGE_TEMPLATE_PREFIX } from "../core/lb-constants.js";
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
import { ATTR_UNKNOWN_PAGE, PAGE_TEMPLATE_PREFIX, } from "../core/lb-constants.js";
|
|
24
|
+
/**
|
|
25
|
+
* The hub calls showModal() on whatever carries lb-unknown-page (hub/lb-hub.ts),
|
|
26
|
+
* so a chrome that puts the attribute on anything else would fail at
|
|
27
|
+
* runtime, on whichever page happens to 404 first, rather than at build
|
|
28
|
+
* time. The attribute is optional; only a wrong element on it is an error.
|
|
29
|
+
*/
|
|
30
|
+
function checkUnknownPageDialog(chromeFile, expandedBody) {
|
|
31
|
+
const fragment = JSDOM.fragment(expandedBody);
|
|
32
|
+
const el = fragment.querySelector(`[${ATTR_UNKNOWN_PAGE}]`);
|
|
33
|
+
if (!el)
|
|
34
|
+
return;
|
|
35
|
+
if (el.tagName !== "DIALOG") {
|
|
36
|
+
throw new Error(`assemble: '${chromeFile}' declares ${ATTR_UNKNOWN_PAGE} on ` +
|
|
37
|
+
`<${el.tagName.toLowerCase()}>, must be a <dialog>`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export async function assemble({ chromeFile, pages, scans, }) {
|
|
41
|
+
// One layer per origin, in order, so a later origin's definition overrides
|
|
42
|
+
// an earlier one's for the same tag. Each layer is checked for cycles as it
|
|
43
|
+
// lands, against everything merged so far.
|
|
44
|
+
let defs = {};
|
|
45
|
+
for (const scan of scans) {
|
|
46
|
+
defs = await addDefinitions(defs, scan.definitions);
|
|
27
47
|
}
|
|
28
|
-
const defs = await addDefinitions(await loadDefinitions([builtinWidgetsDir]), widgetHtmlFiles);
|
|
29
48
|
const templates = [];
|
|
30
49
|
for (const { name, file } of pages) {
|
|
31
50
|
const authored = await readFile(file, "utf-8");
|
|
@@ -45,6 +64,7 @@ export async function assemble({ chromeFile, pages, widgets, builtinWidgetsDir,
|
|
|
45
64
|
}
|
|
46
65
|
const [whole, bodyAttrs, bodyContent] = body;
|
|
47
66
|
const expandedBody = expand(bodyContent, defs);
|
|
67
|
+
checkUnknownPageDialog(chromeFile, expandedBody);
|
|
48
68
|
const withPages = chromeSource.replace(whole, () => `<body${bodyAttrs}>${expandedBody}\n${templates.join("\n")}\n</body>`);
|
|
49
69
|
return {
|
|
50
70
|
html: await formatHtml(withPages),
|
package/dist/build/cli.d.ts
CHANGED
|
@@ -2,26 +2,34 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* loadbare-app-build — assemble a chrome file and its pages into one HTML
|
|
4
4
|
* document, and bundle the client script for exactly the custom elements
|
|
5
|
-
* that document uses. See docs/getting-started.md.
|
|
5
|
+
* that document uses. See docs/tutorials/000-getting-started.md.
|
|
6
6
|
*
|
|
7
|
-
* loadbare-app-build [--src src] [--out dist] [--watch]
|
|
7
|
+
* loadbare-app-build [--src src] [--out dist] [--watch] [--minify]
|
|
8
8
|
*
|
|
9
|
-
* `--src` names the
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
9
|
+
* `--src` names the application's own tree: the one `chrome.html` file,
|
|
10
|
+
* every `*.page.html` page, its `*.hooks.ts`/`*.queries.ts` pairs, and
|
|
11
|
+
* `imports.ts` if there is one — see build/locations.ts. It is also the last
|
|
12
|
+
* origin in the cascade that supplies widget definitions, widget scripts and
|
|
13
|
+
* stylesheets; this package's own widgets come first and each package named
|
|
14
|
+
* in `imports.ts` in between, all scanned the same way — see
|
|
15
|
+
* build/origins.ts.
|
|
16
|
+
*
|
|
17
|
+
* The assembled document is written to `<out>/app.html`; the client bundle
|
|
18
|
+
* to `<out>/client.js`, by way of a generated `<out>/client-entry.ts` — see
|
|
15
19
|
* build/elements.ts for how a tag is resolved to the script that registers
|
|
16
20
|
* it. When any page has a hooks or queries file, the hub registry that used
|
|
17
21
|
* to be hand-maintained is written to `<out>/pages.ts` — see build/pages.ts.
|
|
18
|
-
* Every
|
|
19
|
-
*
|
|
20
|
-
*
|
|
22
|
+
* Every origin's stylesheets are concatenated in that same cascade order and
|
|
23
|
+
* written to `<out>/app.css` — see build/styles.ts.
|
|
24
|
+
*
|
|
25
|
+
* `--minify` minifies both output files: esbuild's own minifier for
|
|
26
|
+
* `client.js`, as part of the same bundling pass, and esbuild's CSS
|
|
27
|
+
* transform for `app.css`, as a pass over the concatenation above. `app.html`
|
|
28
|
+
* is never minified — it is markup an application may still want to read.
|
|
21
29
|
*
|
|
22
30
|
* Without `--watch`, this runs once and exits. With it, every `.html`,
|
|
23
31
|
* `.ts` and `.css` file under `<src>` is watched — a page, a widget's
|
|
24
|
-
* markup, a widget's class, a stylesheet, and `
|
|
32
|
+
* markup, a widget's class, a stylesheet, and `imports.ts` all feed the
|
|
25
33
|
* same build — and a rebuild that throws is reported without stopping the
|
|
26
34
|
* watch. There is no dev server and no browser reload here, only the files
|
|
27
35
|
* on disk staying current for the next manual refresh.
|
package/dist/build/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../build/cli.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../build/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG"}
|
package/dist/build/cli.js
CHANGED
|
@@ -2,26 +2,34 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* loadbare-app-build — assemble a chrome file and its pages into one HTML
|
|
4
4
|
* document, and bundle the client script for exactly the custom elements
|
|
5
|
-
* that document uses. See docs/getting-started.md.
|
|
5
|
+
* that document uses. See docs/tutorials/000-getting-started.md.
|
|
6
6
|
*
|
|
7
|
-
* loadbare-app-build [--src src] [--out dist] [--watch]
|
|
7
|
+
* loadbare-app-build [--src src] [--out dist] [--watch] [--minify]
|
|
8
8
|
*
|
|
9
|
-
* `--src` names the
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
9
|
+
* `--src` names the application's own tree: the one `chrome.html` file,
|
|
10
|
+
* every `*.page.html` page, its `*.hooks.ts`/`*.queries.ts` pairs, and
|
|
11
|
+
* `imports.ts` if there is one — see build/locations.ts. It is also the last
|
|
12
|
+
* origin in the cascade that supplies widget definitions, widget scripts and
|
|
13
|
+
* stylesheets; this package's own widgets come first and each package named
|
|
14
|
+
* in `imports.ts` in between, all scanned the same way — see
|
|
15
|
+
* build/origins.ts.
|
|
16
|
+
*
|
|
17
|
+
* The assembled document is written to `<out>/app.html`; the client bundle
|
|
18
|
+
* to `<out>/client.js`, by way of a generated `<out>/client-entry.ts` — see
|
|
15
19
|
* build/elements.ts for how a tag is resolved to the script that registers
|
|
16
20
|
* it. When any page has a hooks or queries file, the hub registry that used
|
|
17
21
|
* to be hand-maintained is written to `<out>/pages.ts` — see build/pages.ts.
|
|
18
|
-
* Every
|
|
19
|
-
*
|
|
20
|
-
*
|
|
22
|
+
* Every origin's stylesheets are concatenated in that same cascade order and
|
|
23
|
+
* written to `<out>/app.css` — see build/styles.ts.
|
|
24
|
+
*
|
|
25
|
+
* `--minify` minifies both output files: esbuild's own minifier for
|
|
26
|
+
* `client.js`, as part of the same bundling pass, and esbuild's CSS
|
|
27
|
+
* transform for `app.css`, as a pass over the concatenation above. `app.html`
|
|
28
|
+
* is never minified — it is markup an application may still want to read.
|
|
21
29
|
*
|
|
22
30
|
* Without `--watch`, this runs once and exits. With it, every `.html`,
|
|
23
31
|
* `.ts` and `.css` file under `<src>` is watched — a page, a widget's
|
|
24
|
-
* markup, a widget's class, a stylesheet, and `
|
|
32
|
+
* markup, a widget's class, a stylesheet, and `imports.ts` all feed the
|
|
25
33
|
* same build — and a rebuild that throws is reported without stopping the
|
|
26
34
|
* watch. There is no dev server and no browser reload here, only the files
|
|
27
35
|
* on disk staying current for the next manual refresh.
|
|
@@ -33,6 +41,7 @@ import * as esbuild from "esbuild";
|
|
|
33
41
|
import { assemble } from "./assemble.js";
|
|
34
42
|
import { clientEntrySource, resolveElements } from "./elements.js";
|
|
35
43
|
import { resolveLocations } from "./locations.js";
|
|
44
|
+
import { cssFrom, scanAll } from "./origins.js";
|
|
36
45
|
import { pagesSource } from "./pages.js";
|
|
37
46
|
import { stylesSource } from "./styles.js";
|
|
38
47
|
const { values } = parseArgs({
|
|
@@ -40,6 +49,7 @@ const { values } = parseArgs({
|
|
|
40
49
|
src: { type: "string", default: "src" },
|
|
41
50
|
out: { type: "string", default: "dist" },
|
|
42
51
|
watch: { type: "boolean", default: false },
|
|
52
|
+
minify: { type: "boolean", default: false },
|
|
43
53
|
},
|
|
44
54
|
});
|
|
45
55
|
const srcDir = values.src;
|
|
@@ -48,16 +58,18 @@ async function build() {
|
|
|
48
58
|
const outFile = path.join(locations.outDir, "app.html");
|
|
49
59
|
const entryFile = path.join(locations.outDir, "client-entry.ts");
|
|
50
60
|
const clientFile = path.join(locations.outDir, "client.js");
|
|
51
|
-
const
|
|
61
|
+
const scans = await scanAll(locations, srcDir, locations.importsFile);
|
|
62
|
+
const { html, usedTags } = await assemble({ ...locations, scans });
|
|
52
63
|
await mkdir(locations.outDir, { recursive: true });
|
|
53
64
|
await writeFile(outFile, html, "utf-8");
|
|
54
|
-
const { resolved } =
|
|
65
|
+
const { resolved } = resolveElements({ used: usedTags, scans });
|
|
55
66
|
await writeFile(entryFile, clientEntrySource(resolved, locations.outDir), "utf-8");
|
|
56
67
|
await esbuild.build({
|
|
57
68
|
entryPoints: [entryFile],
|
|
58
69
|
bundle: true,
|
|
59
70
|
format: "iife",
|
|
60
71
|
outfile: clientFile,
|
|
72
|
+
minify: values.minify,
|
|
61
73
|
});
|
|
62
74
|
const generatedPages = pagesSource(locations.pages, locations.pageSources, locations.outDir, locations.packageName);
|
|
63
75
|
let pagesMessage = "";
|
|
@@ -66,10 +78,16 @@ async function build() {
|
|
|
66
78
|
await writeFile(pagesFile, generatedPages, "utf-8");
|
|
67
79
|
pagesMessage = ` and ${pagesFile}`;
|
|
68
80
|
}
|
|
69
|
-
const
|
|
81
|
+
const concatenatedCss = await stylesSource(cssFrom(scans));
|
|
70
82
|
let cssMessage = "";
|
|
71
|
-
if (
|
|
83
|
+
if (concatenatedCss) {
|
|
72
84
|
const cssFile = path.join(locations.outDir, "app.css");
|
|
85
|
+
const generatedCss = values.minify
|
|
86
|
+
? (await esbuild.transform(concatenatedCss, {
|
|
87
|
+
loader: "css",
|
|
88
|
+
minify: true,
|
|
89
|
+
})).code
|
|
90
|
+
: concatenatedCss;
|
|
73
91
|
await writeFile(cssFile, generatedCss, "utf-8");
|
|
74
92
|
cssMessage = ` and ${cssFile}`;
|
|
75
93
|
}
|
package/dist/build/elements.d.ts
CHANGED
|
@@ -3,28 +3,23 @@
|
|
|
3
3
|
* and finding the script to import for it when it can.
|
|
4
4
|
*
|
|
5
5
|
* A used tag is valid if it has a script, a definition, or both:
|
|
6
|
-
* - a script registers the class that upgrades it.
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* directory — or a third party's, declared by tag in `elements.ts`.
|
|
12
|
-
* - a definition (an `.html` file, built-in or local) expands the tag's
|
|
13
|
-
* content at build time. A widget with only a definition and no script
|
|
14
|
-
* is markup only: expansion already gave it everything it will ever
|
|
15
|
-
* have, and the tag survives just as an inert wrapper (see expand.ts).
|
|
6
|
+
* - a script registers the class that upgrades it.
|
|
7
|
+
* - a definition (an `.html` file) expands the tag's content at build
|
|
8
|
+
* time. A widget with only a definition and no script is markup only:
|
|
9
|
+
* expansion already gave it everything it will ever have, and the tag
|
|
10
|
+
* survives as an inert wrapper (see expand.ts).
|
|
16
11
|
*
|
|
17
12
|
* A tag with neither — no script anywhere and no definition — would do
|
|
18
13
|
* nothing were it ever to reach the browser, so that is an error.
|
|
19
14
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
15
|
+
* Both halves are looked for in the same ordered origins, and the later
|
|
16
|
+
* origin wins: an application's own script overrides one from a package it
|
|
17
|
+
* imported, which overrides a built-in. Two files claiming one tag *within*
|
|
18
|
+
* one origin is the error case, and build/origins.ts raises it while
|
|
19
|
+
* scanning. Nothing is scanned here.
|
|
24
20
|
*/
|
|
25
|
-
import {
|
|
26
|
-
|
|
27
|
-
export type ElementManifest = Record<string, string>;
|
|
21
|
+
import type { OriginScan } from "./origins.js";
|
|
22
|
+
export { loadElementManifest, type ElementManifest } from "./origins.js";
|
|
28
23
|
/** A resolved tag: a bare specifier to import, or a local file to import by relative path. */
|
|
29
24
|
export type Resolved = {
|
|
30
25
|
kind: "specifier";
|
|
@@ -33,24 +28,15 @@ export type Resolved = {
|
|
|
33
28
|
kind: "file";
|
|
34
29
|
value: string;
|
|
35
30
|
};
|
|
36
|
-
/**
|
|
37
|
-
* `elements.ts`, executed rather than parsed — it runs through the same
|
|
38
|
-
* loader as the rest of the build, so it is ordinary TypeScript, not a data
|
|
39
|
-
* format with its own rules.
|
|
40
|
-
*/
|
|
41
|
-
export declare function loadElementManifest(file: string): Promise<ElementManifest>;
|
|
42
31
|
export interface ResolveOptions {
|
|
43
32
|
used: Set<string>;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
builtinWidgetsDir: string;
|
|
47
|
-
builtinHubDir: string;
|
|
48
|
-
packageName: string;
|
|
33
|
+
/** Every origin, already scanned, in cascade order — see build/origins.ts. */
|
|
34
|
+
scans: OriginScan[];
|
|
49
35
|
}
|
|
50
36
|
export interface ResolveResult {
|
|
51
37
|
resolved: Map<string, Resolved>;
|
|
52
38
|
}
|
|
53
|
-
export declare function resolveElements({ used,
|
|
39
|
+
export declare function resolveElements({ used, scans, }: ResolveOptions): ResolveResult;
|
|
54
40
|
/**
|
|
55
41
|
* The generated client entry point — every custom element the assembled
|
|
56
42
|
* document actually uses, and nothing else. Written to `outDir` so a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"elements.d.ts","sourceRoot":"","sources":["../../build/elements.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"elements.d.ts","sourceRoot":"","sources":["../../build/elements.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,mBAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAEzE,8FAA8F;AAC9F,MAAM,MAAM,QAAQ,GAClB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAClB,8EAA8E;IAC9E,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CACjC;AAED,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,KAAK,GACN,EAAE,cAAc,GAAG,aAAa,CAiChC;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,EAC/B,MAAM,EAAE,MAAM,GACb,MAAM,CAcR"}
|