astro 2.10.12 → 2.10.14
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/client-base.d.ts +2 -1
- package/components/ViewTransitions.astro +80 -37
- package/content-types.template.d.ts +2 -5
- package/dist/core/config/schema.d.ts +146 -1
- package/dist/core/config/schema.js +2 -0
- package/dist/core/constants.js +1 -1
- package/dist/core/dev/dev.js +1 -1
- package/dist/core/messages.js +2 -2
- package/dist/runtime/server/render/any.js +8 -2
- package/dist/runtime/server/render/astro/render-template.js +11 -3
- package/dist/runtime/server/render/common.d.ts +2 -1
- package/dist/runtime/server/render/component.js +1 -11
- package/dist/runtime/server/render/util.d.ts +23 -0
- package/dist/runtime/server/render/util.js +17 -0
- package/package.json +1 -1
package/client-base.d.ts
CHANGED
|
@@ -53,6 +53,7 @@ declare module 'astro:assets' {
|
|
|
53
53
|
| import('./dist/assets/types.js').UnresolvedImageTransform
|
|
54
54
|
) => Promise<import('./dist/assets/types.js').GetImageResult>;
|
|
55
55
|
getConfiguredImageService: typeof import('./dist/assets/index.js').getConfiguredImageService;
|
|
56
|
+
imageConfig: import('./dist/@types/astro').AstroConfig['image'];
|
|
56
57
|
Image: typeof import('./components/Image.astro').default;
|
|
57
58
|
};
|
|
58
59
|
|
|
@@ -69,7 +70,7 @@ declare module 'astro:assets' {
|
|
|
69
70
|
export type RemoteImageProps = Simplify<
|
|
70
71
|
import('./dist/assets/types.js').RemoteImageProps<ImgAttributes>
|
|
71
72
|
>;
|
|
72
|
-
export const { getImage, getConfiguredImageService, Image }: AstroAssets;
|
|
73
|
+
export const { getImage, getConfiguredImageService, imageConfig, Image }: AstroAssets;
|
|
73
74
|
}
|
|
74
75
|
|
|
75
76
|
declare module 'astro:transitions' {
|
|
@@ -20,22 +20,21 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|
|
20
20
|
type Events = 'astro:load' | 'astro:beforeload';
|
|
21
21
|
|
|
22
22
|
const persistState = (state: State) => history.replaceState(state, '');
|
|
23
|
+
const supportsViewTransitions = !!document.startViewTransition;
|
|
24
|
+
const transitionEnabledOnThisPage = () =>
|
|
25
|
+
!!document.querySelector('[name="astro-view-transitions-enabled"]');
|
|
26
|
+
const triggerEvent = (name: Events) => document.dispatchEvent(new Event(name));
|
|
27
|
+
const onload = () => triggerEvent('astro:load');
|
|
28
|
+
const PERSIST_ATTR = 'data-astro-transition-persist';
|
|
23
29
|
|
|
24
30
|
// The History API does not tell you if navigation is forward or back, so
|
|
25
31
|
// you can figure it using an index. On pushState the index is incremented so you
|
|
26
32
|
// can use that to determine popstate if going forward or back.
|
|
27
33
|
let currentHistoryIndex = history.state?.index || 0;
|
|
28
|
-
if (!history.state) {
|
|
34
|
+
if (!history.state && transitionEnabledOnThisPage()) {
|
|
29
35
|
persistState({ index: currentHistoryIndex, scrollY: 0 });
|
|
30
36
|
}
|
|
31
37
|
|
|
32
|
-
const supportsViewTransitions = !!document.startViewTransition;
|
|
33
|
-
const transitionEnabledOnThisPage = () =>
|
|
34
|
-
!!document.querySelector('[name="astro-view-transitions-enabled"]');
|
|
35
|
-
const triggerEvent = (name: Events) => document.dispatchEvent(new Event(name));
|
|
36
|
-
const onload = () => triggerEvent('astro:load');
|
|
37
|
-
const PERSIST_ATTR = 'data-astro-transition-persist';
|
|
38
|
-
|
|
39
38
|
const throttle = (cb: (...args: any[]) => any, delay: number) => {
|
|
40
39
|
let wait = false;
|
|
41
40
|
// During the waiting time additional events are lost.
|
|
@@ -137,6 +136,18 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|
|
137
136
|
// Remove them before swapping.
|
|
138
137
|
doc.querySelectorAll('head noscript').forEach((el) => el.remove());
|
|
139
138
|
|
|
139
|
+
// swap attributes of the html element
|
|
140
|
+
// - delete all attributes from the current document
|
|
141
|
+
// - insert all attributes from doc
|
|
142
|
+
// - reinsert all original attributes that are named 'data-astro-*'
|
|
143
|
+
const html = document.documentElement;
|
|
144
|
+
const astro = [...html.attributes].filter(
|
|
145
|
+
({ name }) => (html.removeAttribute(name), name.startsWith('data-astro-'))
|
|
146
|
+
);
|
|
147
|
+
[...doc.documentElement.attributes, ...astro].forEach(({ name, value }) =>
|
|
148
|
+
html.setAttribute(name, value)
|
|
149
|
+
);
|
|
150
|
+
|
|
140
151
|
// Swap head
|
|
141
152
|
for (const el of Array.from(document.head.children)) {
|
|
142
153
|
const newEl = persistedHeadElement(el);
|
|
@@ -165,14 +176,21 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|
|
165
176
|
}
|
|
166
177
|
}
|
|
167
178
|
|
|
179
|
+
// Simulate scroll behavior of Safari and
|
|
180
|
+
// Chromium based browsers (Chrome, Edge, Opera, ...)
|
|
181
|
+
scrollTo({ left: 0, top: 0, behavior: 'instant' });
|
|
182
|
+
|
|
168
183
|
if (state?.scrollY === 0 && location.hash) {
|
|
169
184
|
const id = decodeURIComponent(location.hash.slice(1));
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
185
|
+
const elem = document.getElementById(id);
|
|
186
|
+
// prefer scrollIntoView() over scrollTo() because it takes scroll-padding into account
|
|
187
|
+
if (elem) {
|
|
188
|
+
state.scrollY = elem.offsetTop;
|
|
189
|
+
persistState(state); // first guess, later updated by scroll handler
|
|
190
|
+
elem.scrollIntoView(); // for Firefox, this should better be {behavior: 'instant'}
|
|
191
|
+
}
|
|
192
|
+
} else if (state && state.scrollY !== 0) {
|
|
193
|
+
scrollTo(0, state.scrollY); // usings default scrollBehavior
|
|
176
194
|
}
|
|
177
195
|
|
|
178
196
|
triggerEvent('astro:beforeload');
|
|
@@ -274,34 +292,59 @@ const { fallback = 'animate' } = Astro.props as Props;
|
|
|
274
292
|
// that is going to another page within the same origin. Basically it determines
|
|
275
293
|
// same-origin navigation, but omits special key combos for new tabs, etc.
|
|
276
294
|
if (
|
|
277
|
-
link
|
|
278
|
-
link instanceof HTMLAnchorElement
|
|
279
|
-
link.href
|
|
280
|
-
(
|
|
281
|
-
link.origin
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
ev.
|
|
287
|
-
|
|
288
|
-
!
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
295
|
+
!link ||
|
|
296
|
+
!(link instanceof HTMLAnchorElement) ||
|
|
297
|
+
!link.href ||
|
|
298
|
+
(link.target && link.target !== '_self') ||
|
|
299
|
+
link.origin !== location.origin ||
|
|
300
|
+
ev.button !== 0 || // left clicks only
|
|
301
|
+
ev.metaKey || // new tab (mac)
|
|
302
|
+
ev.ctrlKey || // new tab (windows)
|
|
303
|
+
ev.altKey || // download
|
|
304
|
+
ev.shiftKey || // new window
|
|
305
|
+
ev.defaultPrevented ||
|
|
306
|
+
!transitionEnabledOnThisPage()
|
|
307
|
+
)
|
|
308
|
+
// No page transitions in these cases,
|
|
309
|
+
// Let the browser standard action handle this
|
|
310
|
+
return;
|
|
311
|
+
|
|
312
|
+
// We do not need to handle same page links because there are no page transitions
|
|
313
|
+
// Same page means same path and same query params (but different hash)
|
|
314
|
+
if (location.pathname === link.pathname && location.search === link.search) {
|
|
315
|
+
if (link.hash) {
|
|
316
|
+
// The browser default action will handle navigations with hash fragments
|
|
317
|
+
return;
|
|
318
|
+
} else {
|
|
319
|
+
// Special case: self link without hash
|
|
320
|
+
// If handed to the browser it will reload the page
|
|
321
|
+
// But we want to handle it like any other same page navigation
|
|
322
|
+
// So we scroll to the top of the page but do not start page transitions
|
|
323
|
+
ev.preventDefault();
|
|
324
|
+
persistState({ ...history.state, scrollY });
|
|
325
|
+
scrollTo({ left: 0, top: 0, behavior: 'instant' });
|
|
326
|
+
if (location.hash) {
|
|
327
|
+
// last target was different
|
|
328
|
+
const newState: State = { index: ++currentHistoryIndex, scrollY: 0 };
|
|
329
|
+
history.pushState(newState, '', link.href);
|
|
330
|
+
}
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
299
333
|
}
|
|
334
|
+
|
|
335
|
+
// these are the cases we will handle: same origin, different page
|
|
336
|
+
ev.preventDefault();
|
|
337
|
+
navigate('forward', link.href, { index: ++currentHistoryIndex, scrollY: 0 });
|
|
338
|
+
const newState: State = { index: currentHistoryIndex, scrollY };
|
|
339
|
+
persistState({ index: currentHistoryIndex - 1, scrollY });
|
|
340
|
+
history.pushState(newState, '', link.href);
|
|
300
341
|
});
|
|
342
|
+
|
|
301
343
|
addEventListener('popstate', (ev) => {
|
|
302
|
-
if (!transitionEnabledOnThisPage()) {
|
|
344
|
+
if (!transitionEnabledOnThisPage() && ev.state) {
|
|
303
345
|
// The current page doesn't haven't View Transitions,
|
|
304
346
|
// respect that with a full page reload
|
|
347
|
+
// -- but only for transition managed by us (ev.state is set)
|
|
305
348
|
location.reload();
|
|
306
349
|
return;
|
|
307
350
|
}
|
|
@@ -53,12 +53,9 @@ declare module 'astro:content' {
|
|
|
53
53
|
|
|
54
54
|
type BaseSchemaWithoutEffects =
|
|
55
55
|
| import('astro/zod').AnyZodObject
|
|
56
|
-
| import('astro/zod').ZodUnion<
|
|
56
|
+
| import('astro/zod').ZodUnion<[BaseSchemaWithoutEffects, ...BaseSchemaWithoutEffects[]]>
|
|
57
57
|
| import('astro/zod').ZodDiscriminatedUnion<string, import('astro/zod').AnyZodObject[]>
|
|
58
|
-
| import('astro/zod').ZodIntersection<
|
|
59
|
-
import('astro/zod').AnyZodObject,
|
|
60
|
-
import('astro/zod').AnyZodObject
|
|
61
|
-
>;
|
|
58
|
+
| import('astro/zod').ZodIntersection<BaseSchemaWithoutEffects, BaseSchemaWithoutEffects>;
|
|
62
59
|
|
|
63
60
|
type BaseSchema =
|
|
64
61
|
| BaseSchemaWithoutEffects
|
|
@@ -375,7 +375,7 @@ export declare const AstroConfigSchema: z.ZodObject<{
|
|
|
375
375
|
legacy?: {} | undefined;
|
|
376
376
|
}>;
|
|
377
377
|
export type AstroConfigType = z.infer<typeof AstroConfigSchema>;
|
|
378
|
-
export declare function createRelativeSchema(cmd: string, fileProtocolRoot: string): z.ZodEffects<z.ZodObject<{
|
|
378
|
+
export declare function createRelativeSchema(cmd: string, fileProtocolRoot: string): z.ZodEffects<z.ZodEffects<z.ZodObject<{
|
|
379
379
|
output: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"static">, z.ZodLiteral<"server">, z.ZodLiteral<"hybrid">]>>>;
|
|
380
380
|
redirects: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodObject<{
|
|
381
381
|
status: z.ZodUnion<[z.ZodLiteral<300>, z.ZodLiteral<301>, z.ZodLiteral<302>, z.ZodLiteral<303>, z.ZodLiteral<304>, z.ZodLiteral<307>, z.ZodLiteral<308>]>;
|
|
@@ -893,4 +893,149 @@ export declare function createRelativeSchema(cmd: string, fileProtocolRoot: stri
|
|
|
893
893
|
optimizeHoistedScript?: boolean | undefined;
|
|
894
894
|
} | undefined;
|
|
895
895
|
legacy?: {} | undefined;
|
|
896
|
+
}>, {
|
|
897
|
+
site?: string | undefined;
|
|
898
|
+
adapter?: {
|
|
899
|
+
name: string;
|
|
900
|
+
hooks: {};
|
|
901
|
+
} | undefined;
|
|
902
|
+
output: "server" | "static" | "hybrid";
|
|
903
|
+
server: {
|
|
904
|
+
headers?: OutgoingHttpHeaders | undefined;
|
|
905
|
+
host: string | boolean;
|
|
906
|
+
port: number;
|
|
907
|
+
open: boolean;
|
|
908
|
+
streaming: boolean;
|
|
909
|
+
};
|
|
910
|
+
redirects: Record<string, string | {
|
|
911
|
+
status: 300 | 301 | 302 | 303 | 304 | 307 | 308;
|
|
912
|
+
destination: string;
|
|
913
|
+
}>;
|
|
914
|
+
root: import("url").URL;
|
|
915
|
+
srcDir: import("url").URL;
|
|
916
|
+
publicDir: import("url").URL;
|
|
917
|
+
outDir: import("url").URL;
|
|
918
|
+
cacheDir: import("url").URL;
|
|
919
|
+
compressHTML: boolean;
|
|
920
|
+
base: string;
|
|
921
|
+
trailingSlash: "ignore" | "always" | "never";
|
|
922
|
+
scopedStyleStrategy: "where" | "class";
|
|
923
|
+
integrations: {
|
|
924
|
+
name: string;
|
|
925
|
+
hooks: {};
|
|
926
|
+
}[];
|
|
927
|
+
build: {
|
|
928
|
+
assetsPrefix?: string | undefined;
|
|
929
|
+
format: "file" | "directory";
|
|
930
|
+
client: import("url").URL;
|
|
931
|
+
server: import("url").URL;
|
|
932
|
+
assets: string;
|
|
933
|
+
serverEntry: string;
|
|
934
|
+
redirects: boolean;
|
|
935
|
+
inlineStylesheets: "always" | "never" | "auto";
|
|
936
|
+
split: boolean;
|
|
937
|
+
excludeMiddleware: boolean;
|
|
938
|
+
};
|
|
939
|
+
image: {
|
|
940
|
+
service: {
|
|
941
|
+
entrypoint: string;
|
|
942
|
+
config: Record<string, any>;
|
|
943
|
+
};
|
|
944
|
+
domains: string[];
|
|
945
|
+
remotePatterns: {
|
|
946
|
+
port?: string | undefined;
|
|
947
|
+
protocol?: string | undefined;
|
|
948
|
+
hostname?: string | undefined;
|
|
949
|
+
pathname?: string | undefined;
|
|
950
|
+
}[];
|
|
951
|
+
};
|
|
952
|
+
markdown: {
|
|
953
|
+
drafts: boolean;
|
|
954
|
+
syntaxHighlight: false | "shiki" | "prism";
|
|
955
|
+
shikiConfig: {
|
|
956
|
+
langs: ILanguageRegistration[];
|
|
957
|
+
theme: string | import("shiki").IShikiTheme;
|
|
958
|
+
wrap: boolean | null;
|
|
959
|
+
};
|
|
960
|
+
remarkPlugins: (string | [string, any] | RemarkPlugin | [RemarkPlugin, any])[];
|
|
961
|
+
rehypePlugins: (string | [string, any] | RehypePlugin | [RehypePlugin, any])[];
|
|
962
|
+
remarkRehype: RemarkRehype;
|
|
963
|
+
gfm: boolean;
|
|
964
|
+
smartypants: boolean;
|
|
965
|
+
};
|
|
966
|
+
vite: ViteUserConfig;
|
|
967
|
+
experimental: {
|
|
968
|
+
assets: boolean;
|
|
969
|
+
viewTransitions: boolean;
|
|
970
|
+
optimizeHoistedScript: boolean;
|
|
971
|
+
};
|
|
972
|
+
legacy: {};
|
|
973
|
+
}, {
|
|
974
|
+
output?: "server" | "static" | "hybrid" | undefined;
|
|
975
|
+
server?: unknown;
|
|
976
|
+
redirects?: Record<string, string | {
|
|
977
|
+
status: 300 | 301 | 302 | 303 | 304 | 307 | 308;
|
|
978
|
+
destination: string;
|
|
979
|
+
}> | undefined;
|
|
980
|
+
root?: string | undefined;
|
|
981
|
+
srcDir?: string | undefined;
|
|
982
|
+
publicDir?: string | undefined;
|
|
983
|
+
outDir?: string | undefined;
|
|
984
|
+
cacheDir?: string | undefined;
|
|
985
|
+
site?: string | undefined;
|
|
986
|
+
compressHTML?: boolean | undefined;
|
|
987
|
+
base?: string | undefined;
|
|
988
|
+
trailingSlash?: "ignore" | "always" | "never" | undefined;
|
|
989
|
+
scopedStyleStrategy?: "where" | "class" | undefined;
|
|
990
|
+
adapter?: {
|
|
991
|
+
hooks?: {} | undefined;
|
|
992
|
+
name: string;
|
|
993
|
+
} | undefined;
|
|
994
|
+
integrations?: unknown;
|
|
995
|
+
build?: {
|
|
996
|
+
format?: "file" | "directory" | undefined;
|
|
997
|
+
client?: string | undefined;
|
|
998
|
+
server?: string | undefined;
|
|
999
|
+
assets?: string | undefined;
|
|
1000
|
+
serverEntry?: string | undefined;
|
|
1001
|
+
redirects?: boolean | undefined;
|
|
1002
|
+
inlineStylesheets?: "always" | "never" | "auto" | undefined;
|
|
1003
|
+
split?: boolean | undefined;
|
|
1004
|
+
excludeMiddleware?: boolean | undefined;
|
|
1005
|
+
assetsPrefix?: string | undefined;
|
|
1006
|
+
} | undefined;
|
|
1007
|
+
image?: {
|
|
1008
|
+
domains?: string[] | undefined;
|
|
1009
|
+
remotePatterns?: {
|
|
1010
|
+
port?: string | undefined;
|
|
1011
|
+
protocol?: string | undefined;
|
|
1012
|
+
hostname?: string | undefined;
|
|
1013
|
+
pathname?: string | undefined;
|
|
1014
|
+
}[] | undefined;
|
|
1015
|
+
service: {
|
|
1016
|
+
config?: Record<string, any> | undefined;
|
|
1017
|
+
entrypoint: string;
|
|
1018
|
+
};
|
|
1019
|
+
} | undefined;
|
|
1020
|
+
markdown?: {
|
|
1021
|
+
drafts?: boolean | undefined;
|
|
1022
|
+
syntaxHighlight?: false | "shiki" | "prism" | undefined;
|
|
1023
|
+
shikiConfig?: {
|
|
1024
|
+
langs?: ILanguageRegistration[] | undefined;
|
|
1025
|
+
theme?: string | import("shiki").IShikiTheme | undefined;
|
|
1026
|
+
wrap?: boolean | null | undefined;
|
|
1027
|
+
} | undefined;
|
|
1028
|
+
remarkPlugins?: (string | [string, any] | RemarkPlugin | [RemarkPlugin, any])[] | undefined;
|
|
1029
|
+
rehypePlugins?: (string | [string, any] | RehypePlugin | [RehypePlugin, any])[] | undefined;
|
|
1030
|
+
remarkRehype?: RemarkRehype | undefined;
|
|
1031
|
+
gfm?: boolean | undefined;
|
|
1032
|
+
smartypants?: boolean | undefined;
|
|
1033
|
+
} | undefined;
|
|
1034
|
+
vite?: ViteUserConfig | undefined;
|
|
1035
|
+
experimental?: {
|
|
1036
|
+
assets?: boolean | undefined;
|
|
1037
|
+
viewTransitions?: boolean | undefined;
|
|
1038
|
+
optimizeHoistedScript?: boolean | undefined;
|
|
1039
|
+
} | undefined;
|
|
1040
|
+
legacy?: {} | undefined;
|
|
896
1041
|
}>;
|
|
@@ -245,6 +245,8 @@ A future version of Astro will stop using the site pathname when producing <link
|
|
|
245
245
|
config.base = prependForwardSlash(appendForwardSlash(trimmedBase));
|
|
246
246
|
}
|
|
247
247
|
return config;
|
|
248
|
+
}).refine((obj) => !obj.outDir.toString().startsWith(obj.publicDir.toString()), {
|
|
249
|
+
message: "`outDir` must not be placed inside `publicDir` to prevent an infinite loop. Please adjust the directory configuration and try again"
|
|
248
250
|
});
|
|
249
251
|
return AstroConfigRelativeSchema;
|
|
250
252
|
}
|
package/dist/core/constants.js
CHANGED
package/dist/core/dev/dev.js
CHANGED
|
@@ -23,7 +23,7 @@ async function dev(inlineConfig) {
|
|
|
23
23
|
base: restart.container.settings.config.base
|
|
24
24
|
})
|
|
25
25
|
);
|
|
26
|
-
const currentVersion = "2.10.
|
|
26
|
+
const currentVersion = "2.10.14";
|
|
27
27
|
if (currentVersion.includes("-")) {
|
|
28
28
|
warn(logging, null, msg.prerelease({ currentVersion }));
|
|
29
29
|
}
|
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.10.
|
|
50
|
+
const version = "2.10.14";
|
|
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.10.
|
|
236
|
+
`v${"2.10.14"}`
|
|
237
237
|
)} ${headline}`
|
|
238
238
|
);
|
|
239
239
|
}
|
|
@@ -2,6 +2,7 @@ import { escapeHTML, isHTMLString, markHTMLString } from "../escape.js";
|
|
|
2
2
|
import { isAstroComponentInstance, isRenderTemplateResult } from "./astro/index.js";
|
|
3
3
|
import { isRenderInstance } from "./common.js";
|
|
4
4
|
import { SlotString } from "./slot.js";
|
|
5
|
+
import { renderToBufferDestination } from "./util.js";
|
|
5
6
|
async function renderChild(destination, child) {
|
|
6
7
|
child = await child;
|
|
7
8
|
if (child instanceof SlotString) {
|
|
@@ -9,8 +10,13 @@ async function renderChild(destination, child) {
|
|
|
9
10
|
} else if (isHTMLString(child)) {
|
|
10
11
|
destination.write(child);
|
|
11
12
|
} else if (Array.isArray(child)) {
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
const childRenders = child.map((c) => {
|
|
14
|
+
return renderToBufferDestination((bufferDestination) => {
|
|
15
|
+
return renderChild(bufferDestination, c);
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
for (const childRender of childRenders) {
|
|
19
|
+
await childRender.renderToFinalDestination(destination);
|
|
14
20
|
}
|
|
15
21
|
} else if (typeof child === "function") {
|
|
16
22
|
await renderChild(destination, child());
|
|
@@ -2,6 +2,7 @@ var _a;
|
|
|
2
2
|
import { markHTMLString } from "../../escape.js";
|
|
3
3
|
import { isPromise } from "../../util.js";
|
|
4
4
|
import { renderChild } from "../any.js";
|
|
5
|
+
import { renderToBufferDestination } from "../util.js";
|
|
5
6
|
const renderTemplateResultSym = Symbol.for("astro.renderTemplateResult");
|
|
6
7
|
class RenderTemplateResult {
|
|
7
8
|
constructor(htmlParts, expressions) {
|
|
@@ -21,12 +22,19 @@ class RenderTemplateResult {
|
|
|
21
22
|
});
|
|
22
23
|
}
|
|
23
24
|
async render(destination) {
|
|
25
|
+
const expRenders = this.expressions.map((exp) => {
|
|
26
|
+
return renderToBufferDestination((bufferDestination) => {
|
|
27
|
+
if (exp || exp === 0) {
|
|
28
|
+
return renderChild(bufferDestination, exp);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
});
|
|
24
32
|
for (let i = 0; i < this.htmlParts.length; i++) {
|
|
25
33
|
const html = this.htmlParts[i];
|
|
26
|
-
const
|
|
34
|
+
const expRender = expRenders[i];
|
|
27
35
|
destination.write(markHTMLString(html));
|
|
28
|
-
if (
|
|
29
|
-
await
|
|
36
|
+
if (expRender) {
|
|
37
|
+
await expRender.renderToFinalDestination(destination);
|
|
30
38
|
}
|
|
31
39
|
}
|
|
32
40
|
}
|
|
@@ -18,8 +18,9 @@ export interface RenderDestination {
|
|
|
18
18
|
write(chunk: RenderDestinationChunk): void;
|
|
19
19
|
}
|
|
20
20
|
export interface RenderInstance {
|
|
21
|
-
render
|
|
21
|
+
render: RenderFunction;
|
|
22
22
|
}
|
|
23
|
+
export type RenderFunction = (destination: RenderDestination) => Promise<void> | void;
|
|
23
24
|
export declare const Fragment: unique symbol;
|
|
24
25
|
export declare const Renderer: unique symbol;
|
|
25
26
|
export declare const encoder: TextEncoder;
|
|
@@ -322,19 +322,9 @@ async function renderHTMLComponent(result, Component, _props, slots = {}) {
|
|
|
322
322
|
}
|
|
323
323
|
function renderAstroComponent(result, displayName, Component, props, slots = {}) {
|
|
324
324
|
const instance = createAstroComponentInstance(result, displayName, Component, props, slots);
|
|
325
|
-
const bufferChunks = [];
|
|
326
|
-
const bufferDestination = {
|
|
327
|
-
write: (chunk) => bufferChunks.push(chunk)
|
|
328
|
-
};
|
|
329
|
-
const renderPromise = instance.render(bufferDestination);
|
|
330
325
|
return {
|
|
331
326
|
async render(destination) {
|
|
332
|
-
|
|
333
|
-
destination.write(chunk);
|
|
334
|
-
}
|
|
335
|
-
bufferChunks.length = 0;
|
|
336
|
-
bufferDestination.write = (chunk) => destination.write(chunk);
|
|
337
|
-
await renderPromise;
|
|
327
|
+
await instance.render(destination);
|
|
338
328
|
}
|
|
339
329
|
};
|
|
340
330
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { SSRElement } from '../../../@types/astro';
|
|
2
|
+
import type { RenderFunction } from './common.js';
|
|
2
3
|
export declare const voidElementNames: RegExp;
|
|
3
4
|
export declare const toAttributeString: (value: any, shouldEscape?: boolean) => any;
|
|
4
5
|
export declare function defineScriptVars(vars: Record<any, any>): any;
|
|
@@ -6,3 +7,25 @@ export declare function formatList(values: string[]): string;
|
|
|
6
7
|
export declare function addAttribute(value: any, key: string, shouldEscape?: boolean): any;
|
|
7
8
|
export declare function internalSpreadAttributes(values: Record<any, any>, shouldEscape?: boolean): any;
|
|
8
9
|
export declare function renderElement(name: string, { props: _props, children }: SSRElement, shouldEscape?: boolean): string;
|
|
10
|
+
/**
|
|
11
|
+
* Executes the `bufferRenderFunction` to prerender it into a buffer destination, and return a promise
|
|
12
|
+
* with an object containing the `renderToFinalDestination` function to flush the buffer to the final
|
|
13
|
+
* destination.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* // Render components in parallel ahead of time
|
|
18
|
+
* const finalRenders = [ComponentA, ComponentB].map((comp) => {
|
|
19
|
+
* return renderToBufferDestination(async (bufferDestination) => {
|
|
20
|
+
* await renderComponentToDestination(bufferDestination);
|
|
21
|
+
* });
|
|
22
|
+
* });
|
|
23
|
+
* // Render array of components serially
|
|
24
|
+
* for (const finalRender of finalRenders) {
|
|
25
|
+
* await finalRender.renderToFinalDestination(finalDestination);
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function renderToBufferDestination(bufferRenderFunction: RenderFunction): {
|
|
30
|
+
renderToFinalDestination: RenderFunction;
|
|
31
|
+
};
|
|
@@ -103,12 +103,29 @@ function renderElement(name, { props: _props, children = "" }, shouldEscape = tr
|
|
|
103
103
|
}
|
|
104
104
|
return `<${name}${internalSpreadAttributes(props, shouldEscape)}>${children}</${name}>`;
|
|
105
105
|
}
|
|
106
|
+
function renderToBufferDestination(bufferRenderFunction) {
|
|
107
|
+
const bufferChunks = [];
|
|
108
|
+
const bufferDestination = {
|
|
109
|
+
write: (chunk) => bufferChunks.push(chunk)
|
|
110
|
+
};
|
|
111
|
+
const renderPromise = bufferRenderFunction(bufferDestination);
|
|
112
|
+
return {
|
|
113
|
+
async renderToFinalDestination(destination) {
|
|
114
|
+
for (const chunk of bufferChunks) {
|
|
115
|
+
destination.write(chunk);
|
|
116
|
+
}
|
|
117
|
+
bufferDestination.write = (chunk) => destination.write(chunk);
|
|
118
|
+
await renderPromise;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
106
122
|
export {
|
|
107
123
|
addAttribute,
|
|
108
124
|
defineScriptVars,
|
|
109
125
|
formatList,
|
|
110
126
|
internalSpreadAttributes,
|
|
111
127
|
renderElement,
|
|
128
|
+
renderToBufferDestination,
|
|
112
129
|
toAttributeString,
|
|
113
130
|
voidElementNames
|
|
114
131
|
};
|