astro 2.9.0 → 2.9.2
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/astro-jsx.d.ts +1 -0
- package/components/ViewTransitions.astro +19 -1
- package/components/viewtransitions.css +12 -0
- package/dist/@types/astro.d.ts +1 -1
- package/dist/assets/image-endpoint.d.ts +1 -1
- package/dist/assets/internal.js +2 -2
- package/dist/assets/services/service.d.ts +5 -5
- package/dist/assets/utils/index.d.ts +3 -0
- package/dist/assets/utils/index.js +8 -1
- package/dist/assets/vite-plugin-assets.js +0 -54
- package/dist/cli/load-settings.js +2 -1
- package/dist/config/index.js +1 -1
- package/dist/core/config/settings.d.ts +2 -2
- package/dist/core/config/settings.js +5 -5
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/dev/restart.js +1 -1
- package/dist/core/messages.js +2 -2
- package/dist/runtime/server/jsx.js +5 -1
- package/dist/runtime/server/render/astro/factory.d.ts +0 -1
- package/dist/runtime/server/render/astro/factory.js +1 -18
- package/dist/runtime/server/render/astro/index.d.ts +2 -1
- package/dist/runtime/server/render/astro/index.js +3 -1
- package/dist/runtime/server/render/astro/render.d.ts +4 -0
- package/dist/runtime/server/render/astro/render.js +119 -0
- package/dist/runtime/server/render/common.d.ts +8 -0
- package/dist/runtime/server/render/common.js +12 -3
- package/dist/runtime/server/render/page.js +18 -89
- package/dist/vite-plugin-astro/compile.js +0 -1
- package/dist/vite-plugin-jsx/index.js +0 -1
- package/dist/vite-plugin-markdown/index.js +1 -1
- package/package.json +2 -2
package/astro-jsx.d.ts
CHANGED
|
@@ -901,6 +901,7 @@ declare namespace astroHTML.JSX {
|
|
|
901
901
|
crossorigin?: string | undefined | null;
|
|
902
902
|
defer?: boolean | string | undefined | null;
|
|
903
903
|
fetchpriority?: 'auto' | 'high' | 'low' | undefined | null;
|
|
904
|
+
referrerpolicy?: HTMLAttributeReferrerPolicy | undefined | null;
|
|
904
905
|
integrity?: string | undefined | null;
|
|
905
906
|
nomodule?: boolean | string | undefined | null;
|
|
906
907
|
nonce?: string | undefined | null;
|
|
@@ -47,6 +47,19 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|
|
47
47
|
doc.documentElement.dataset.astroTransition = dir;
|
|
48
48
|
const swap = () => document.documentElement.replaceWith(doc.documentElement);
|
|
49
49
|
|
|
50
|
+
// Wait on links to finish, to prevent FOUC
|
|
51
|
+
const links = Array.from(doc.querySelectorAll('head link[rel=stylesheet]')).map(
|
|
52
|
+
(link) =>
|
|
53
|
+
new Promise((resolve) => {
|
|
54
|
+
const c = link.cloneNode();
|
|
55
|
+
['load', 'error'].forEach((evName) => c.addEventListener(evName, resolve));
|
|
56
|
+
document.head.append(c);
|
|
57
|
+
})
|
|
58
|
+
);
|
|
59
|
+
if (links.length) {
|
|
60
|
+
await Promise.all(links);
|
|
61
|
+
}
|
|
62
|
+
|
|
50
63
|
if (fallback === 'animate') {
|
|
51
64
|
let isAnimating = false;
|
|
52
65
|
addEventListener('animationstart', () => (isAnimating = true), { once: true });
|
|
@@ -128,7 +141,12 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|
|
128
141
|
}
|
|
129
142
|
});
|
|
130
143
|
window.addEventListener('popstate', () => {
|
|
131
|
-
if (!transitionEnabledOnThisPage())
|
|
144
|
+
if (!transitionEnabledOnThisPage()) {
|
|
145
|
+
// The current page doesn't haven't View Transitions,
|
|
146
|
+
// respect that with a full page reload
|
|
147
|
+
location.reload();
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
132
150
|
const nextIndex = history.state?.index ?? currentHistoryIndex + 1;
|
|
133
151
|
const direction: Direction = nextIndex > currentHistoryIndex ? 'forward' : 'back';
|
|
134
152
|
navigate(direction, location.href);
|
|
@@ -42,3 +42,15 @@
|
|
|
42
42
|
transform: translateX(-100%);
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
+
|
|
46
|
+
@media (prefers-reduced-motion) {
|
|
47
|
+
::view-transition-group(*),
|
|
48
|
+
::view-transition-old(*),
|
|
49
|
+
::view-transition-new(*) {
|
|
50
|
+
animation: none !important;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
[data-astro-transition-scope] {
|
|
54
|
+
animation: none !important;
|
|
55
|
+
}
|
|
56
|
+
}
|
package/dist/@types/astro.d.ts
CHANGED
|
@@ -1173,7 +1173,7 @@ export interface AstroUserConfig {
|
|
|
1173
1173
|
* @version 2.9.0
|
|
1174
1174
|
* @description
|
|
1175
1175
|
* Enable experimental support for the `<ViewTransitions / >` component. With this enabled
|
|
1176
|
-
* you can opt-in to
|
|
1176
|
+
* you can opt-in to [view transitions](https://docs.astro.build/en/guides/view-transitions/) on a per-page basis using this component
|
|
1177
1177
|
* and enable animations with the `transition:animate` directive.
|
|
1178
1178
|
*
|
|
1179
1179
|
* ```js
|
package/dist/assets/internal.js
CHANGED
|
@@ -29,8 +29,8 @@ async function getImage(options, serviceConfig) {
|
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
31
|
const service = await getConfiguredImageService();
|
|
32
|
-
const validatedOptions = service.validateOptions ? service.validateOptions(options, serviceConfig) : options;
|
|
33
|
-
let imageURL = service.getURL(validatedOptions, serviceConfig);
|
|
32
|
+
const validatedOptions = service.validateOptions ? await service.validateOptions(options, serviceConfig) : options;
|
|
33
|
+
let imageURL = await service.getURL(validatedOptions, serviceConfig);
|
|
34
34
|
if (isLocalService(service) && globalThis.astroAsset.addStaticImage) {
|
|
35
35
|
imageURL = globalThis.astroAsset.addStaticImage(validatedOptions);
|
|
36
36
|
}
|
|
@@ -12,14 +12,14 @@ interface SharedServiceProps {
|
|
|
12
12
|
* For external services, this should point to the URL your images are coming from, for instance, `/_vercel/image`
|
|
13
13
|
*
|
|
14
14
|
*/
|
|
15
|
-
getURL: (options: ImageTransform, serviceConfig: Record<string, any>) => string
|
|
15
|
+
getURL: (options: ImageTransform, serviceConfig: Record<string, any>) => string | Promise<string>;
|
|
16
16
|
/**
|
|
17
17
|
* Return any additional HTML attributes separate from `src` that your service requires to show the image properly.
|
|
18
18
|
*
|
|
19
19
|
* For example, you might want to return the `width` and `height` to avoid CLS, or a particular `class` or `style`.
|
|
20
20
|
* In most cases, you'll want to return directly what your user supplied you, minus the attributes that were used to generate the image.
|
|
21
21
|
*/
|
|
22
|
-
getHTMLAttributes?: (options: ImageTransform, serviceConfig: Record<string, any>) => Record<string, any
|
|
22
|
+
getHTMLAttributes?: (options: ImageTransform, serviceConfig: Record<string, any>) => Record<string, any> | Promise<Record<string, any>>;
|
|
23
23
|
/**
|
|
24
24
|
* Validate and return the options passed by the user.
|
|
25
25
|
*
|
|
@@ -28,7 +28,7 @@ interface SharedServiceProps {
|
|
|
28
28
|
*
|
|
29
29
|
* This method should returns options, and can be used to set defaults (ex: a default output format to be used if the user didn't specify one.)
|
|
30
30
|
*/
|
|
31
|
-
validateOptions?: (options: ImageTransform, serviceConfig: Record<string, any>) => ImageTransform
|
|
31
|
+
validateOptions?: (options: ImageTransform, serviceConfig: Record<string, any>) => ImageTransform | Promise<ImageTransform>;
|
|
32
32
|
}
|
|
33
33
|
export type ExternalImageService = SharedServiceProps;
|
|
34
34
|
export type LocalImageTransform = {
|
|
@@ -37,11 +37,11 @@ export type LocalImageTransform = {
|
|
|
37
37
|
};
|
|
38
38
|
export interface LocalImageService extends SharedServiceProps {
|
|
39
39
|
/**
|
|
40
|
-
* Parse the requested parameters passed in the URL from `getURL` back into an object to be used later by `transform
|
|
40
|
+
* Parse the requested parameters passed in the URL from `getURL` back into an object to be used later by `transform`.
|
|
41
41
|
*
|
|
42
42
|
* In most cases, this will get query parameters using, for example, `params.get('width')` and return those.
|
|
43
43
|
*/
|
|
44
|
-
parseURL: (url: URL, serviceConfig: Record<string, any>) => LocalImageTransform | undefined
|
|
44
|
+
parseURL: (url: URL, serviceConfig: Record<string, any>) => LocalImageTransform | undefined | Promise<LocalImageTransform> | Promise<undefined>;
|
|
45
45
|
/**
|
|
46
46
|
* Performs the image transformations on the input image and returns both the binary data and
|
|
47
47
|
* final image format of the optimized image.
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { emitESMImage } from "./emitAsset.js";
|
|
2
|
+
import { imageMetadata } from "./metadata.js";
|
|
3
|
+
import { getOrigQueryParams } from "./queryParams.js";
|
|
4
|
+
import { hashTransform, propsToFilename } from "./transformToPath.js";
|
|
2
5
|
export {
|
|
3
|
-
emitESMImage
|
|
6
|
+
emitESMImage,
|
|
7
|
+
getOrigQueryParams,
|
|
8
|
+
hashTransform,
|
|
9
|
+
imageMetadata,
|
|
10
|
+
propsToFilename
|
|
4
11
|
};
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { bold } from "kleur/colors";
|
|
2
2
|
import MagicString from "magic-string";
|
|
3
|
-
import mime from "mime/lite.js";
|
|
4
|
-
import fs from "node:fs/promises";
|
|
5
|
-
import { Readable } from "node:stream";
|
|
6
3
|
import { fileURLToPath } from "node:url";
|
|
7
4
|
import { normalizePath } from "vite";
|
|
8
5
|
import { error } from "../core/logger/core.js";
|
|
@@ -14,10 +11,7 @@ import {
|
|
|
14
11
|
} from "../core/path.js";
|
|
15
12
|
import { VIRTUAL_MODULE_ID, VIRTUAL_SERVICE_ID } from "./consts.js";
|
|
16
13
|
import { isESMImportedImage } from "./internal.js";
|
|
17
|
-
import { isLocalService } from "./services/service.js";
|
|
18
14
|
import { emitESMImage } from "./utils/emitAsset.js";
|
|
19
|
-
import { imageMetadata } from "./utils/metadata.js";
|
|
20
|
-
import { getOrigQueryParams } from "./utils/queryParams.js";
|
|
21
15
|
import { hashTransform, propsToFilename } from "./utils/transformToPath.js";
|
|
22
16
|
const resolvedVirtualModuleId = "\0" + VIRTUAL_MODULE_ID;
|
|
23
17
|
const rawRE = /(?:\?|&)raw(?:&|$)/;
|
|
@@ -84,54 +78,6 @@ function assets({
|
|
|
84
78
|
`;
|
|
85
79
|
}
|
|
86
80
|
},
|
|
87
|
-
// Handle serving images during development
|
|
88
|
-
configureServer(server) {
|
|
89
|
-
server.middlewares.use(async (req, res, next) => {
|
|
90
|
-
var _a2, _b;
|
|
91
|
-
if ((_a2 = req.url) == null ? void 0 : _a2.startsWith("/_image")) {
|
|
92
|
-
if (!isLocalService(globalThis.astroAsset.imageService)) {
|
|
93
|
-
return next();
|
|
94
|
-
}
|
|
95
|
-
const url = new URL(req.url, "file:");
|
|
96
|
-
if (!url.searchParams.has("href")) {
|
|
97
|
-
return next();
|
|
98
|
-
}
|
|
99
|
-
const filePath = (_b = url.searchParams.get("href")) == null ? void 0 : _b.slice("/@fs".length);
|
|
100
|
-
const filePathURL = new URL("." + filePath, "file:");
|
|
101
|
-
const file = await fs.readFile(filePathURL);
|
|
102
|
-
let meta = getOrigQueryParams(filePathURL.searchParams);
|
|
103
|
-
if (!meta) {
|
|
104
|
-
meta = await imageMetadata(filePathURL, file);
|
|
105
|
-
if (!meta) {
|
|
106
|
-
return next();
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
const transform = await globalThis.astroAsset.imageService.parseURL(
|
|
110
|
-
url,
|
|
111
|
-
settings.config.image.service.config
|
|
112
|
-
);
|
|
113
|
-
if (transform === void 0) {
|
|
114
|
-
error(logging, "image", `Failed to parse transform for ${url}`);
|
|
115
|
-
}
|
|
116
|
-
let data = file;
|
|
117
|
-
let format = meta.format;
|
|
118
|
-
if (transform) {
|
|
119
|
-
const result = await globalThis.astroAsset.imageService.transform(
|
|
120
|
-
file,
|
|
121
|
-
transform,
|
|
122
|
-
settings.config.image.service.config
|
|
123
|
-
);
|
|
124
|
-
data = result.data;
|
|
125
|
-
format = result.format;
|
|
126
|
-
}
|
|
127
|
-
res.setHeader("Content-Type", mime.getType(format) ?? `image/${format}`);
|
|
128
|
-
res.setHeader("Cache-Control", "max-age=360000");
|
|
129
|
-
const stream = Readable.from(data);
|
|
130
|
-
return stream.pipe(res);
|
|
131
|
-
}
|
|
132
|
-
return next();
|
|
133
|
-
});
|
|
134
|
-
},
|
|
135
81
|
buildStart() {
|
|
136
82
|
if (mode != "build") {
|
|
137
83
|
return;
|
|
@@ -17,10 +17,11 @@ async function loadSettings({ cmd, flags, logging }) {
|
|
|
17
17
|
await handleConfigError(e, { cmd, cwd: root, flags, logging });
|
|
18
18
|
return {};
|
|
19
19
|
});
|
|
20
|
+
const mode = cmd === "build" ? "build" : "dev";
|
|
20
21
|
if (!initialAstroConfig)
|
|
21
22
|
return;
|
|
22
23
|
telemetry.record(event.eventCliSession(cmd, initialUserConfig, flags));
|
|
23
|
-
return createSettings(initialAstroConfig, root);
|
|
24
|
+
return createSettings(initialAstroConfig, mode, root);
|
|
24
25
|
}
|
|
25
26
|
async function handleConfigError(e, { cmd, cwd, flags, logging }) {
|
|
26
27
|
const path = await resolveConfigPath({ cwd, flags, fs });
|
package/dist/config/index.js
CHANGED
|
@@ -26,7 +26,7 @@ function getViteConfig(inlineConfig) {
|
|
|
26
26
|
level: "info"
|
|
27
27
|
};
|
|
28
28
|
const { astroConfig: config } = await openConfig({ cmd });
|
|
29
|
-
const settings = createSettings(config, inlineConfig.root);
|
|
29
|
+
const settings = createSettings(config, cmd, inlineConfig.root);
|
|
30
30
|
await runHookConfigSetup({ settings, command: cmd, logging });
|
|
31
31
|
const viteConfig = await createVite(
|
|
32
32
|
{
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { AstroConfig, AstroSettings, AstroUserConfig } from '../../@types/astro';
|
|
2
|
-
export declare function createBaseSettings(config: AstroConfig): AstroSettings;
|
|
3
|
-
export declare function createSettings(config: AstroConfig, cwd?: string): AstroSettings;
|
|
2
|
+
export declare function createBaseSettings(config: AstroConfig, mode: 'build' | 'dev'): AstroSettings;
|
|
3
|
+
export declare function createSettings(config: AstroConfig, mode: 'build' | 'dev', cwd?: string): AstroSettings;
|
|
4
4
|
export declare function createDefaultDevSettings(userConfig?: AstroUserConfig, root?: string | URL): Promise<AstroSettings>;
|
|
@@ -12,14 +12,14 @@ import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from "./../constants.js";
|
|
|
12
12
|
import { createDefaultDevConfig } from "./config.js";
|
|
13
13
|
import { AstroTimer } from "./timer.js";
|
|
14
14
|
import { loadTSConfig } from "./tsconfig.js";
|
|
15
|
-
function createBaseSettings(config) {
|
|
15
|
+
function createBaseSettings(config, mode) {
|
|
16
16
|
const { contentDir } = getContentPaths(config);
|
|
17
17
|
return {
|
|
18
18
|
config,
|
|
19
19
|
tsConfig: void 0,
|
|
20
20
|
tsConfigPath: void 0,
|
|
21
21
|
adapter: void 0,
|
|
22
|
-
injectedRoutes: config.experimental.assets && isServerLikeOutput(config) ? [{ pattern: "/_image", entryPoint: "astro/assets/image-endpoint", prerender: false }] : [],
|
|
22
|
+
injectedRoutes: config.experimental.assets && (isServerLikeOutput(config) || mode === "dev") ? [{ pattern: "/_image", entryPoint: "astro/assets/image-endpoint", prerender: false }] : [],
|
|
23
23
|
pageExtensions: [".astro", ".html", ...SUPPORTED_MARKDOWN_FILE_EXTENSIONS],
|
|
24
24
|
contentEntryTypes: [markdownContentEntryType],
|
|
25
25
|
dataEntryTypes: [
|
|
@@ -92,9 +92,9 @@ function createBaseSettings(config) {
|
|
|
92
92
|
timer: new AstroTimer()
|
|
93
93
|
};
|
|
94
94
|
}
|
|
95
|
-
function createSettings(config, cwd) {
|
|
95
|
+
function createSettings(config, mode, cwd) {
|
|
96
96
|
const tsconfig = loadTSConfig(cwd);
|
|
97
|
-
const settings = createBaseSettings(config);
|
|
97
|
+
const settings = createBaseSettings(config, mode);
|
|
98
98
|
const watchFiles = (tsconfig == null ? void 0 : tsconfig.exists) ? [tsconfig.path, ...tsconfig.extendedPaths] : [];
|
|
99
99
|
if (cwd) {
|
|
100
100
|
watchFiles.push(fileURLToPath(new URL("./package.json", pathToFileURL(cwd))));
|
|
@@ -109,7 +109,7 @@ async function createDefaultDevSettings(userConfig = {}, root) {
|
|
|
109
109
|
root = fileURLToPath(root);
|
|
110
110
|
}
|
|
111
111
|
const config = await createDefaultDevConfig(userConfig, root);
|
|
112
|
-
return createBaseSettings(config);
|
|
112
|
+
return createBaseSettings(config, "dev");
|
|
113
113
|
}
|
|
114
114
|
export {
|
|
115
115
|
createBaseSettings,
|
package/dist/core/constants.js
CHANGED
package/dist/core/dev/dev.js
CHANGED
|
@@ -54,7 +54,7 @@ async function dev(settings, options) {
|
|
|
54
54
|
isRestart: options.isRestart
|
|
55
55
|
})
|
|
56
56
|
);
|
|
57
|
-
const currentVersion = "2.9.
|
|
57
|
+
const currentVersion = "2.9.2";
|
|
58
58
|
if (currentVersion.includes("-")) {
|
|
59
59
|
warn(options.logging, null, msg.prerelease({ currentVersion }));
|
|
60
60
|
}
|
package/dist/core/dev/restart.js
CHANGED
|
@@ -62,7 +62,7 @@ async function restartContainer({
|
|
|
62
62
|
});
|
|
63
63
|
info(logging, "astro", logMsg + "\n");
|
|
64
64
|
let astroConfig = newConfig.astroConfig;
|
|
65
|
-
const settings = createSettings(astroConfig, resolvedRoot);
|
|
65
|
+
const settings = createSettings(astroConfig, "dev", resolvedRoot);
|
|
66
66
|
await close();
|
|
67
67
|
return {
|
|
68
68
|
container: await createRestartedContainer(container, settings, needsStart),
|
package/dist/core/messages.js
CHANGED
|
@@ -47,7 +47,7 @@ function serverStart({
|
|
|
47
47
|
base,
|
|
48
48
|
isRestart = false
|
|
49
49
|
}) {
|
|
50
|
-
const version = "2.9.
|
|
50
|
+
const version = "2.9.2";
|
|
51
51
|
const localPrefix = `${dim("\u2503")} Local `;
|
|
52
52
|
const networkPrefix = `${dim("\u2503")} Network `;
|
|
53
53
|
const emptyPrefix = " ".repeat(11);
|
|
@@ -233,7 +233,7 @@ function printHelp({
|
|
|
233
233
|
message.push(
|
|
234
234
|
linebreak(),
|
|
235
235
|
` ${bgGreen(black(` ${commandName} `))} ${green(
|
|
236
|
-
`v${"2.9.
|
|
236
|
+
`v${"2.9.2"}`
|
|
237
237
|
)} ${headline}`
|
|
238
238
|
);
|
|
239
239
|
}
|
|
@@ -77,7 +77,11 @@ Did you forget to import the component or is it possible there is a typo?`);
|
|
|
77
77
|
props[key] = value;
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
|
-
const
|
|
80
|
+
const str = await renderToString(result, vnode.type, props, slots);
|
|
81
|
+
if (str instanceof Response) {
|
|
82
|
+
throw str;
|
|
83
|
+
}
|
|
84
|
+
const html = markHTMLString(str);
|
|
81
85
|
return html;
|
|
82
86
|
}
|
|
83
87
|
case (!vnode.type && vnode.type !== 0):
|
|
@@ -9,5 +9,4 @@ export interface AstroComponentFactory {
|
|
|
9
9
|
propagation?: PropagationHint;
|
|
10
10
|
}
|
|
11
11
|
export declare function isAstroComponentFactory(obj: any): obj is AstroComponentFactory;
|
|
12
|
-
export declare function renderToString(result: SSRResult, componentFactory: AstroComponentFactory, props: any, children: any): Promise<string>;
|
|
13
12
|
export declare function isAPropagatingComponent(result: SSRResult, factory: AstroComponentFactory): boolean;
|
|
@@ -1,22 +1,6 @@
|
|
|
1
|
-
import { HTMLParts } from "../common.js";
|
|
2
|
-
import { isHeadAndContent } from "./head-and-content.js";
|
|
3
|
-
import { renderAstroTemplateResult } from "./render-template.js";
|
|
4
1
|
function isAstroComponentFactory(obj) {
|
|
5
2
|
return obj == null ? false : obj.isAstroComponentFactory === true;
|
|
6
3
|
}
|
|
7
|
-
async function renderToString(result, componentFactory, props, children) {
|
|
8
|
-
const factoryResult = await componentFactory(result, props, children);
|
|
9
|
-
if (factoryResult instanceof Response) {
|
|
10
|
-
const response = factoryResult;
|
|
11
|
-
throw response;
|
|
12
|
-
}
|
|
13
|
-
let parts = new HTMLParts();
|
|
14
|
-
const templateResult = isHeadAndContent(factoryResult) ? factoryResult.content : factoryResult;
|
|
15
|
-
for await (const chunk of renderAstroTemplateResult(templateResult)) {
|
|
16
|
-
parts.append(chunk, result);
|
|
17
|
-
}
|
|
18
|
-
return parts.toString();
|
|
19
|
-
}
|
|
20
4
|
function isAPropagatingComponent(result, factory) {
|
|
21
5
|
let hint = factory.propagation || "none";
|
|
22
6
|
if (factory.moduleId && result.componentMetadata.has(factory.moduleId) && hint === "none") {
|
|
@@ -26,6 +10,5 @@ function isAPropagatingComponent(result, factory) {
|
|
|
26
10
|
}
|
|
27
11
|
export {
|
|
28
12
|
isAPropagatingComponent,
|
|
29
|
-
isAstroComponentFactory
|
|
30
|
-
renderToString
|
|
13
|
+
isAstroComponentFactory
|
|
31
14
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export type { AstroComponentFactory } from './factory';
|
|
2
|
-
export { isAstroComponentFactory
|
|
2
|
+
export { isAstroComponentFactory } from './factory.js';
|
|
3
3
|
export { createHeadAndContent, isHeadAndContent } from './head-and-content.js';
|
|
4
4
|
export type { AstroComponentInstance } from './instance';
|
|
5
5
|
export { createAstroComponentInstance, isAstroComponentInstance } from './instance.js';
|
|
6
6
|
export { isRenderTemplateResult, renderAstroTemplateResult, renderTemplate, } from './render-template.js';
|
|
7
|
+
export { renderToReadableStream, renderToString } from './render.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isAstroComponentFactory
|
|
1
|
+
import { isAstroComponentFactory } from "./factory.js";
|
|
2
2
|
import { createHeadAndContent, isHeadAndContent } from "./head-and-content.js";
|
|
3
3
|
import { createAstroComponentInstance, isAstroComponentInstance } from "./instance.js";
|
|
4
4
|
import {
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
renderAstroTemplateResult,
|
|
7
7
|
renderTemplate
|
|
8
8
|
} from "./render-template.js";
|
|
9
|
+
import { renderToReadableStream, renderToString } from "./render.js";
|
|
9
10
|
export {
|
|
10
11
|
createAstroComponentInstance,
|
|
11
12
|
createHeadAndContent,
|
|
@@ -15,5 +16,6 @@ export {
|
|
|
15
16
|
isRenderTemplateResult,
|
|
16
17
|
renderAstroTemplateResult,
|
|
17
18
|
renderTemplate,
|
|
19
|
+
renderToReadableStream,
|
|
18
20
|
renderToString
|
|
19
21
|
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { RouteData, SSRResult } from '../../../../@types/astro';
|
|
2
|
+
import type { AstroComponentFactory } from './factory.js';
|
|
3
|
+
export declare function renderToString(result: SSRResult, componentFactory: AstroComponentFactory, props: any, children: any, isPage?: boolean, route?: RouteData): Promise<string | Response>;
|
|
4
|
+
export declare function renderToReadableStream(result: SSRResult, componentFactory: AstroComponentFactory, props: any, children: any, isPage?: boolean, route?: RouteData): Promise<ReadableStream | Response>;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { AstroError, AstroErrorData } from "../../../../core/errors/index.js";
|
|
2
|
+
import { chunkToByteArray, chunkToString, encoder } from "../common.js";
|
|
3
|
+
import { isHeadAndContent } from "./head-and-content.js";
|
|
4
|
+
import { isRenderTemplateResult, renderAstroTemplateResult } from "./render-template.js";
|
|
5
|
+
async function renderToString(result, componentFactory, props, children, isPage = false, route) {
|
|
6
|
+
const templateResult = await callComponentAsTemplateResultOrResponse(
|
|
7
|
+
result,
|
|
8
|
+
componentFactory,
|
|
9
|
+
props,
|
|
10
|
+
children,
|
|
11
|
+
route
|
|
12
|
+
);
|
|
13
|
+
if (templateResult instanceof Response)
|
|
14
|
+
return templateResult;
|
|
15
|
+
let str = "";
|
|
16
|
+
let renderedFirstPageChunk = false;
|
|
17
|
+
const destination = {
|
|
18
|
+
write(chunk) {
|
|
19
|
+
if (isPage && !renderedFirstPageChunk) {
|
|
20
|
+
renderedFirstPageChunk = true;
|
|
21
|
+
if (!/<!doctype html/i.test(String(chunk))) {
|
|
22
|
+
const doctype = result.compressHTML ? "<!DOCTYPE html>" : "<!DOCTYPE html>\n";
|
|
23
|
+
str += doctype;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (chunk instanceof Response)
|
|
27
|
+
return;
|
|
28
|
+
str += chunkToString(result, chunk);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
for await (const chunk of renderAstroTemplateResult(templateResult)) {
|
|
32
|
+
destination.write(chunk);
|
|
33
|
+
}
|
|
34
|
+
return str;
|
|
35
|
+
}
|
|
36
|
+
async function renderToReadableStream(result, componentFactory, props, children, isPage = false, route) {
|
|
37
|
+
const templateResult = await callComponentAsTemplateResultOrResponse(
|
|
38
|
+
result,
|
|
39
|
+
componentFactory,
|
|
40
|
+
props,
|
|
41
|
+
children,
|
|
42
|
+
route
|
|
43
|
+
);
|
|
44
|
+
if (templateResult instanceof Response)
|
|
45
|
+
return templateResult;
|
|
46
|
+
if (isPage) {
|
|
47
|
+
await bufferHeadContent(result);
|
|
48
|
+
}
|
|
49
|
+
let renderedFirstPageChunk = false;
|
|
50
|
+
return new ReadableStream({
|
|
51
|
+
start(controller) {
|
|
52
|
+
const destination = {
|
|
53
|
+
write(chunk) {
|
|
54
|
+
if (isPage && !renderedFirstPageChunk) {
|
|
55
|
+
renderedFirstPageChunk = true;
|
|
56
|
+
if (!/<!doctype html/i.test(String(chunk))) {
|
|
57
|
+
const doctype = result.compressHTML ? "<!DOCTYPE html>" : "<!DOCTYPE html>\n";
|
|
58
|
+
controller.enqueue(encoder.encode(doctype));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (chunk instanceof Response) {
|
|
62
|
+
throw new AstroError({
|
|
63
|
+
...AstroErrorData.ResponseSentError
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
const bytes = chunkToByteArray(result, chunk);
|
|
67
|
+
controller.enqueue(bytes);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
(async () => {
|
|
71
|
+
try {
|
|
72
|
+
for await (const chunk of renderAstroTemplateResult(templateResult)) {
|
|
73
|
+
destination.write(chunk);
|
|
74
|
+
}
|
|
75
|
+
controller.close();
|
|
76
|
+
} catch (e) {
|
|
77
|
+
if (AstroError.is(e) && !e.loc) {
|
|
78
|
+
e.setLocation({
|
|
79
|
+
file: route == null ? void 0 : route.component
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
controller.error(e);
|
|
83
|
+
}
|
|
84
|
+
})();
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
async function callComponentAsTemplateResultOrResponse(result, componentFactory, props, children, route) {
|
|
89
|
+
const factoryResult = await componentFactory(result, props, children);
|
|
90
|
+
if (factoryResult instanceof Response) {
|
|
91
|
+
return factoryResult;
|
|
92
|
+
} else if (!isRenderTemplateResult(factoryResult)) {
|
|
93
|
+
throw new AstroError({
|
|
94
|
+
...AstroErrorData.OnlyResponseCanBeReturned,
|
|
95
|
+
message: AstroErrorData.OnlyResponseCanBeReturned.message(route == null ? void 0 : route.route, typeof factoryResult),
|
|
96
|
+
location: {
|
|
97
|
+
file: route == null ? void 0 : route.component
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return isHeadAndContent(factoryResult) ? factoryResult.content : factoryResult;
|
|
102
|
+
}
|
|
103
|
+
async function bufferHeadContent(result) {
|
|
104
|
+
const iterator = result._metadata.propagators.values();
|
|
105
|
+
while (true) {
|
|
106
|
+
const { value, done } = iterator.next();
|
|
107
|
+
if (done) {
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
const returnValue = await value.init(result);
|
|
111
|
+
if (isHeadAndContent(returnValue)) {
|
|
112
|
+
result._metadata.extraHead.push(returnValue.head);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
export {
|
|
117
|
+
renderToReadableStream,
|
|
118
|
+
renderToString
|
|
119
|
+
};
|
|
@@ -2,6 +2,13 @@ import type { SSRResult } from '../../../@types/astro';
|
|
|
2
2
|
import type { RenderInstruction } from './types.js';
|
|
3
3
|
import { HTMLBytes } from '../escape.js';
|
|
4
4
|
import { type SlotString } from './slot.js';
|
|
5
|
+
export interface RenderDestination {
|
|
6
|
+
/**
|
|
7
|
+
* Any rendering logic should call this to construct the HTML output.
|
|
8
|
+
* See the `chunk` parameter for possible writable values
|
|
9
|
+
*/
|
|
10
|
+
write(chunk: string | HTMLBytes | RenderInstruction | Response): void;
|
|
11
|
+
}
|
|
5
12
|
export declare const Fragment: unique symbol;
|
|
6
13
|
export declare const Renderer: unique symbol;
|
|
7
14
|
export declare const encoder: TextEncoder;
|
|
@@ -14,4 +21,5 @@ export declare class HTMLParts {
|
|
|
14
21
|
toString(): string;
|
|
15
22
|
toArrayBuffer(): Uint8Array;
|
|
16
23
|
}
|
|
24
|
+
export declare function chunkToString(result: SSRResult, chunk: string | HTMLBytes | RenderInstruction): string;
|
|
17
25
|
export declare function chunkToByteArray(result: SSRResult, chunk: string | HTMLBytes | RenderInstruction): Uint8Array;
|
|
@@ -78,18 +78,27 @@ class HTMLParts {
|
|
|
78
78
|
return encoder.encode(this.parts);
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
|
+
function chunkToString(result, chunk) {
|
|
82
|
+
if (ArrayBuffer.isView(chunk)) {
|
|
83
|
+
return decoder.decode(chunk);
|
|
84
|
+
} else {
|
|
85
|
+
return stringifyChunk(result, chunk);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
81
88
|
function chunkToByteArray(result, chunk) {
|
|
82
|
-
if (chunk
|
|
89
|
+
if (ArrayBuffer.isView(chunk)) {
|
|
83
90
|
return chunk;
|
|
91
|
+
} else {
|
|
92
|
+
const stringified = stringifyChunk(result, chunk);
|
|
93
|
+
return encoder.encode(stringified.toString());
|
|
84
94
|
}
|
|
85
|
-
let stringified = stringifyChunk(result, chunk);
|
|
86
|
-
return encoder.encode(stringified.toString());
|
|
87
95
|
}
|
|
88
96
|
export {
|
|
89
97
|
Fragment,
|
|
90
98
|
HTMLParts,
|
|
91
99
|
Renderer,
|
|
92
100
|
chunkToByteArray,
|
|
101
|
+
chunkToString,
|
|
93
102
|
decoder,
|
|
94
103
|
encoder,
|
|
95
104
|
stringifyChunk
|
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import { AstroError
|
|
1
|
+
import { AstroError } from "../../../core/errors/index.js";
|
|
2
2
|
import { isHTMLString } from "../escape.js";
|
|
3
3
|
import { createResponse } from "../response.js";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
isHeadAndContent,
|
|
8
|
-
isRenderTemplateResult,
|
|
9
|
-
renderAstroTemplateResult
|
|
10
|
-
} from "./astro/index.js";
|
|
11
|
-
import { HTMLParts, chunkToByteArray, encoder } from "./common.js";
|
|
4
|
+
import { isAstroComponentFactory, isAstroComponentInstance } from "./astro/index.js";
|
|
5
|
+
import { renderToReadableStream, renderToString } from "./astro/render.js";
|
|
6
|
+
import { HTMLParts, encoder } from "./common.js";
|
|
12
7
|
import { renderComponent } from "./component.js";
|
|
13
8
|
import { maybeRenderHead } from "./head.js";
|
|
14
9
|
const needsHeadRenderingSymbol = Symbol.for("astro.needsHeadRendering");
|
|
@@ -34,19 +29,6 @@ async function iterableToHTMLBytes(result, iterable, onDocTypeInjection) {
|
|
|
34
29
|
}
|
|
35
30
|
return parts.toArrayBuffer();
|
|
36
31
|
}
|
|
37
|
-
async function bufferHeadContent(result) {
|
|
38
|
-
const iterator = result._metadata.propagators.values();
|
|
39
|
-
while (true) {
|
|
40
|
-
const { value, done } = iterator.next();
|
|
41
|
-
if (done) {
|
|
42
|
-
break;
|
|
43
|
-
}
|
|
44
|
-
const returnValue = await value.init(result);
|
|
45
|
-
if (isHeadAndContent(returnValue)) {
|
|
46
|
-
result._metadata.extraHead.push(returnValue.head);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
32
|
async function renderPage(result, componentFactory, props, children, streaming, route) {
|
|
51
33
|
var _a, _b;
|
|
52
34
|
if (!isAstroComponentFactory(componentFactory)) {
|
|
@@ -93,75 +75,22 @@ async function renderPage(result, componentFactory, props, children, streaming,
|
|
|
93
75
|
});
|
|
94
76
|
}
|
|
95
77
|
result._metadata.headInTree = ((_b = result.componentMetadata.get(componentFactory.moduleId)) == null ? void 0 : _b.containsHead) ?? false;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
let iterable = renderAstroTemplateResult(templateResult);
|
|
102
|
-
let init = result.response;
|
|
103
|
-
let headers = new Headers(init.headers);
|
|
104
|
-
let body;
|
|
105
|
-
if (streaming) {
|
|
106
|
-
body = new ReadableStream({
|
|
107
|
-
start(controller) {
|
|
108
|
-
async function read() {
|
|
109
|
-
let i = 0;
|
|
110
|
-
try {
|
|
111
|
-
for await (const chunk of iterable) {
|
|
112
|
-
if (isHTMLString(chunk)) {
|
|
113
|
-
if (i === 0) {
|
|
114
|
-
if (!/<!doctype html/i.test(String(chunk))) {
|
|
115
|
-
controller.enqueue(
|
|
116
|
-
encoder.encode(
|
|
117
|
-
`${result.compressHTML ? "<!DOCTYPE html>" : "<!DOCTYPE html>\n"}`
|
|
118
|
-
)
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
if (chunk instanceof Response) {
|
|
124
|
-
throw new AstroError({
|
|
125
|
-
...AstroErrorData.ResponseSentError
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
const bytes = chunkToByteArray(result, chunk);
|
|
129
|
-
controller.enqueue(bytes);
|
|
130
|
-
i++;
|
|
131
|
-
}
|
|
132
|
-
controller.close();
|
|
133
|
-
} catch (e) {
|
|
134
|
-
if (AstroError.is(e) && !e.loc) {
|
|
135
|
-
e.setLocation({
|
|
136
|
-
file: route == null ? void 0 : route.component
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
controller.error(e);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
read();
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
} else {
|
|
146
|
-
body = await iterableToHTMLBytes(result, iterable);
|
|
147
|
-
headers.set("Content-Length", body.byteLength.toString());
|
|
148
|
-
}
|
|
149
|
-
let response = createResponse(body, { ...init, headers });
|
|
150
|
-
return response;
|
|
78
|
+
let body;
|
|
79
|
+
if (streaming) {
|
|
80
|
+
body = await renderToReadableStream(result, componentFactory, props, children, true, route);
|
|
81
|
+
} else {
|
|
82
|
+
body = await renderToString(result, componentFactory, props, children, true, route);
|
|
151
83
|
}
|
|
152
|
-
if (
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
location: {
|
|
160
|
-
file: route == null ? void 0 : route.component
|
|
161
|
-
}
|
|
162
|
-
});
|
|
84
|
+
if (body instanceof Response)
|
|
85
|
+
return body;
|
|
86
|
+
const init = result.response;
|
|
87
|
+
const headers = new Headers(init.headers);
|
|
88
|
+
if (!streaming && typeof body === "string") {
|
|
89
|
+
body = encoder.encode(body);
|
|
90
|
+
headers.set("Content-Length", body.byteLength.toString());
|
|
163
91
|
}
|
|
164
|
-
|
|
92
|
+
const response = createResponse(body, { ...init, headers });
|
|
93
|
+
return response;
|
|
165
94
|
}
|
|
166
95
|
export {
|
|
167
96
|
renderPage
|
|
@@ -121,7 +121,6 @@ function jsx({ settings, logging }) {
|
|
|
121
121
|
tsconfigRaw: {
|
|
122
122
|
compilerOptions: {
|
|
123
123
|
// Ensure client:only imports are treeshaken
|
|
124
|
-
// @ts-expect-error anticipate esbuild 0.18 feature
|
|
125
124
|
verbatimModuleSyntax: false,
|
|
126
125
|
importsNotUsedAsValues: "remove"
|
|
127
126
|
}
|
|
@@ -118,7 +118,7 @@ function markdown({ settings, logging }) {
|
|
|
118
118
|
|
|
119
119
|
function updateImageReferences(html) {
|
|
120
120
|
return html.replaceAll(
|
|
121
|
-
/__ASTRO_IMAGE_="(
|
|
121
|
+
/__ASTRO_IMAGE_="([^"]+)"/gm,
|
|
122
122
|
(full, imagePath) => spreadAttributes({src: images[imagePath].src, ...images[imagePath].attributes})
|
|
123
123
|
);
|
|
124
124
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "astro",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.2",
|
|
4
4
|
"description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "withastro",
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
"typescript": "*",
|
|
156
156
|
"unist-util-visit": "^4.1.2",
|
|
157
157
|
"vfile": "^5.3.7",
|
|
158
|
-
"vite": "^4.
|
|
158
|
+
"vite": "^4.4.6",
|
|
159
159
|
"vitefu": "^0.2.4",
|
|
160
160
|
"which-pm": "^2.0.0",
|
|
161
161
|
"yargs-parser": "^21.1.1",
|