astro 4.5.8 → 4.5.10

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 CHANGED
@@ -526,7 +526,7 @@ declare namespace astroHTML.JSX {
526
526
  | 'search'
527
527
  | 'send'
528
528
  | undefined
529
- | null;
529
+ | null;
530
530
  exportparts?: string | undefined | null;
531
531
  hidden?: boolean | string | undefined | null;
532
532
  id?: string | undefined | null;
@@ -584,6 +584,9 @@ declare namespace astroHTML.JSX {
584
584
  results?: number | string | undefined | null;
585
585
  security?: string | undefined | null;
586
586
  unselectable?: 'on' | 'off' | undefined | null; // Internet Explorer
587
+
588
+ // Allow data- attribute
589
+ [key: `data-${string}`]: any;
587
590
  }
588
591
 
589
592
  type HTMLAttributeReferrerPolicy =
@@ -1344,6 +1347,9 @@ declare namespace astroHTML.JSX {
1344
1347
  yChannelSelector?: string | undefined | null;
1345
1348
  z?: number | string | undefined | null;
1346
1349
  zoomAndPan?: string | undefined | null;
1350
+
1351
+ // Allow data- attribute
1352
+ [key: `data-${string}`]: any;
1347
1353
  }
1348
1354
 
1349
1355
  interface DefinedIntrinsicElements {
@@ -80,7 +80,7 @@ const highlighter = await getCachedHighlighter({
80
80
  ? Object.keys(bundledLanguages).includes(lang)
81
81
  ? lang
82
82
  : 'plaintext'
83
- : lang,
83
+ : (lang as any),
84
84
  ],
85
85
  theme,
86
86
  themes,
@@ -89,7 +89,7 @@ const highlighter = await getCachedHighlighter({
89
89
 
90
90
  const html = highlighter.highlight(code, typeof lang === 'string' ? lang : lang.name, {
91
91
  inline,
92
- attributes: rest,
92
+ attributes: rest as any,
93
93
  });
94
94
  ---
95
95
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  import { getImage, type LocalImageProps, type RemoteImageProps } from 'astro:assets';
3
3
  import type { GetImageResult, ImageOutputFormat } from '../dist/@types/astro';
4
- import { isESMImportedImage } from '../dist/assets/utils/imageKind';
4
+ import { isESMImportedImage, resolveSrc } from '../dist/assets/utils/imageKind';
5
5
  import { AstroError, AstroErrorData } from '../dist/core/errors/index.js';
6
6
  import type { HTMLAttributes } from '../types';
7
7
 
@@ -27,20 +27,27 @@ if (props.alt === undefined || props.alt === null) {
27
27
  throw new AstroError(AstroErrorData.ImageMissingAlt);
28
28
  }
29
29
 
30
+ const originalSrc = await resolveSrc(props.src);
30
31
  const optimizedImages: GetImageResult[] = await Promise.all(
31
32
  formats.map(
32
33
  async (format) =>
33
- await getImage({ ...props, format: format, widths: props.widths, densities: props.densities })
34
+ await getImage({
35
+ ...props,
36
+ src: originalSrc,
37
+ format: format,
38
+ widths: props.widths,
39
+ densities: props.densities,
40
+ })
34
41
  )
35
42
  );
36
43
 
37
44
  let resultFallbackFormat = fallbackFormat ?? defaultFallbackFormat;
38
45
  if (
39
46
  !fallbackFormat &&
40
- isESMImportedImage(props.src) &&
41
- specialFormatsFallback.includes(props.src.format)
47
+ isESMImportedImage(originalSrc) &&
48
+ originalSrc.format in specialFormatsFallback
42
49
  ) {
43
- resultFallbackFormat = props.src.format;
50
+ resultFallbackFormat = originalSrc.format;
44
51
  }
45
52
 
46
53
  const fallbackImage = await getImage({
@@ -1,7 +1,7 @@
1
1
  import { AstroError, AstroErrorData } from "../core/errors/index.js";
2
2
  import { DEFAULT_HASH_PROPS } from "./consts.js";
3
3
  import { isLocalService } from "./services/service.js";
4
- import { isESMImportedImage, isRemoteImage } from "./utils/imageKind.js";
4
+ import { isESMImportedImage, isRemoteImage, resolveSrc } from "./utils/imageKind.js";
5
5
  import { probe } from "./utils/remoteProbe.js";
6
6
  async function getConfiguredImageService() {
7
7
  if (!globalThis?.astroAsset?.imageService) {
@@ -40,7 +40,7 @@ async function getImage(options, imageConfig) {
40
40
  const service = await getConfiguredImageService();
41
41
  const resolvedOptions = {
42
42
  ...options,
43
- src: typeof options.src === "object" && "then" in options.src ? (await options.src).default ?? await options.src : options.src
43
+ src: await resolveSrc(options.src)
44
44
  };
45
45
  if (options.inferSize && isRemoteImage(resolvedOptions.src)) {
46
46
  try {
@@ -1,3 +1,4 @@
1
- import type { ImageMetadata } from '../types.js';
1
+ import type { ImageMetadata, UnresolvedImageTransform } from '../types.js';
2
2
  export declare function isESMImportedImage(src: ImageMetadata | string): src is ImageMetadata;
3
3
  export declare function isRemoteImage(src: ImageMetadata | string): src is string;
4
+ export declare function resolveSrc(src: UnresolvedImageTransform['src']): Promise<string | ImageMetadata>;
@@ -4,7 +4,11 @@ function isESMImportedImage(src) {
4
4
  function isRemoteImage(src) {
5
5
  return typeof src === "string";
6
6
  }
7
+ async function resolveSrc(src) {
8
+ return typeof src === "object" && "then" in src ? (await src).default ?? await src : src;
9
+ }
7
10
  export {
8
11
  isESMImportedImage,
9
- isRemoteImage
12
+ isRemoteImage,
13
+ resolveSrc
10
14
  };
@@ -57,12 +57,18 @@ function assets({
57
57
  export { default as Picture } from "astro/components/Picture.astro";
58
58
 
59
59
  export const imageConfig = ${JSON.stringify(settings.config.image)};
60
- export const outDir = new URL(${JSON.stringify(
60
+ // This is used by the @astrojs/node integration to locate images.
61
+ // It's unused on other platforms, but on some platforms like Netlify (and presumably also Vercel)
62
+ // new URL("dist/...") is interpreted by the bundler as a signal to include that directory
63
+ // in the Lambda bundle, which would bloat the bundle with images.
64
+ // To prevent this, we mark the URL construction as pure,
65
+ // so that it's tree-shaken away for all platforms that don't need it.
66
+ export const outDir = /* #__PURE__ */ new URL(${JSON.stringify(
61
67
  new URL(
62
68
  isServerLikeOutput(settings.config) ? settings.config.build.client : settings.config.outDir
63
69
  )
64
70
  )});
65
- export const assetsDir = new URL(${JSON.stringify(settings.config.build.assets)}, outDir);
71
+ export const assetsDir = /* #__PURE__ */ new URL(${JSON.stringify(settings.config.build.assets)}, outDir);
66
72
  export const getImage = async (options) => await getImageInternal(options, imageConfig);
67
73
  `;
68
74
  }
@@ -1,7 +1,7 @@
1
1
  import { extname } from "node:path";
2
2
  import { pathToFileURL } from "node:url";
3
3
  import { getAssetsPrefix } from "../assets/utils/getAssetsPrefix.js";
4
- import { moduleIsTopLevelPage, walkParentInfos } from "../core/build/graph.js";
4
+ import { getParentModuleInfos, moduleIsTopLevelPage } from "../core/build/graph.js";
5
5
  import { getPageDataByViteID } from "../core/build/internal.js";
6
6
  import { createViteLoader } from "../core/module-loader/vite.js";
7
7
  import { joinPaths, prependForwardSlash } from "../core/path.js";
@@ -147,7 +147,7 @@ function astroConfigBuildPlugin(options, internals) {
147
147
  }
148
148
  } else {
149
149
  for (const id of Object.keys(chunk.modules)) {
150
- for (const [pageInfo] of walkParentInfos(id, ssrPluginContext)) {
150
+ for (const pageInfo of getParentModuleInfos(id, ssrPluginContext)) {
151
151
  if (moduleIsTopLevelPage(pageInfo)) {
152
152
  const pageViteID = pageInfo.id;
153
153
  const pageData = getPageDataByViteID(internals, pageViteID);
@@ -1,13 +1,13 @@
1
1
  import crypto from "node:crypto";
2
2
  import npath from "node:path";
3
3
  import { viteID } from "../util.js";
4
- import { getTopLevelPages } from "./graph.js";
4
+ import { getTopLevelPageModuleInfos } from "./graph.js";
5
5
  const confusingBaseNames = ["404", "500"];
6
6
  function shortHashedName(id, ctx) {
7
- const parents = Array.from(getTopLevelPages(id, ctx));
7
+ const parents = getTopLevelPageModuleInfos(id, ctx);
8
8
  return createNameHash(
9
9
  getFirstParentId(parents),
10
- parents.map(([page]) => page.id)
10
+ parents.map((page) => page.id)
11
11
  );
12
12
  }
13
13
  function createNameHash(baseId, hashIds) {
@@ -26,8 +26,8 @@ function createSlugger(settings) {
26
26
  const map = /* @__PURE__ */ new Map();
27
27
  const sep = "-";
28
28
  return function(id, ctx) {
29
- const parents = Array.from(getTopLevelPages(id, ctx));
30
- const allParentsKey = parents.map(([page]) => page.id).sort().join("-");
29
+ const parents = Array.from(getTopLevelPageModuleInfos(id, ctx));
30
+ const allParentsKey = parents.map((page) => page.id).sort().join("-");
31
31
  const firstParentId = getFirstParentId(parents) || indexPage;
32
32
  let dir = firstParentId;
33
33
  let key = "";
@@ -62,13 +62,13 @@ function createSlugger(settings) {
62
62
  }
63
63
  function getFirstParentId(parents) {
64
64
  for (const parent of parents) {
65
- const id = parent[0].id;
65
+ const id = parent.id;
66
66
  const baseName = npath.parse(id).name;
67
67
  if (!confusingBaseNames.includes(baseName)) {
68
68
  return id;
69
69
  }
70
70
  }
71
- return parents[0]?.[0].id;
71
+ return parents[0]?.id;
72
72
  }
73
73
  const charsToReplaceRe = /[.[\]]/g;
74
74
  const underscoresRe = /_+/g;
@@ -1,8 +1,17 @@
1
1
  import type { GetModuleInfo, ModuleInfo } from 'rollup';
2
- export declare function walkParentInfos(id: string, ctx: {
2
+ interface ExtendedModuleInfo {
3
+ info: ModuleInfo;
4
+ depth: number;
5
+ order: number;
6
+ }
7
+ export declare function getParentExtendedModuleInfos(id: string, ctx: {
3
8
  getModuleInfo: GetModuleInfo;
4
- }, until?: (importer: string) => boolean, depth?: number, order?: number, seen?: Set<string>, childId?: string): Generator<[ModuleInfo, number, number], void, unknown>;
9
+ }, until?: (importer: string) => boolean, depth?: number, order?: number, childId?: string, seen?: Set<string>, accumulated?: ExtendedModuleInfo[]): ExtendedModuleInfo[];
10
+ export declare function getParentModuleInfos(id: string, ctx: {
11
+ getModuleInfo: GetModuleInfo;
12
+ }, until?: (importer: string) => boolean, seen?: Set<string>, accumulated?: ModuleInfo[]): ModuleInfo[];
5
13
  export declare function moduleIsTopLevelPage(info: ModuleInfo): boolean;
6
- export declare function getTopLevelPages(id: string, ctx: {
14
+ export declare function getTopLevelPageModuleInfos(id: string, ctx: {
7
15
  getModuleInfo: GetModuleInfo;
8
- }): Generator<[ModuleInfo, number, number], void, unknown>;
16
+ }): ModuleInfo[];
17
+ export {};
@@ -1,5 +1,5 @@
1
1
  import { ASTRO_PAGE_RESOLVED_MODULE_ID } from "./plugins/plugin-pages.js";
2
- function* walkParentInfos(id, ctx, until, depth = 0, order = 0, seen = /* @__PURE__ */ new Set(), childId = "") {
2
+ function getParentExtendedModuleInfos(id, ctx, until, depth = 0, order = 0, childId = "", seen = /* @__PURE__ */ new Set(), accumulated = []) {
3
3
  seen.add(id);
4
4
  const info = ctx.getModuleInfo(id);
5
5
  if (info) {
@@ -12,30 +12,43 @@ function* walkParentInfos(id, ctx, until, depth = 0, order = 0, seen = /* @__PUR
12
12
  order += idx;
13
13
  }
14
14
  }
15
- yield [info, depth, order];
15
+ accumulated.push({ info, depth, order });
16
16
  }
17
- if (until?.(id))
18
- return;
19
- const importers = (info?.importers || []).concat(info?.dynamicImporters || []);
20
- for (const imp of importers) {
21
- if (seen.has(imp)) {
22
- continue;
17
+ if (info && !until?.(id)) {
18
+ const importers = info.importers.concat(info.dynamicImporters);
19
+ for (const imp of importers) {
20
+ if (!seen.has(imp)) {
21
+ getParentExtendedModuleInfos(imp, ctx, until, depth + 1, order, id, seen, accumulated);
22
+ }
23
23
  }
24
- yield* walkParentInfos(imp, ctx, until, depth + 1, order, seen, id);
25
24
  }
25
+ return accumulated;
26
+ }
27
+ function getParentModuleInfos(id, ctx, until, seen = /* @__PURE__ */ new Set(), accumulated = []) {
28
+ seen.add(id);
29
+ const info = ctx.getModuleInfo(id);
30
+ if (info) {
31
+ accumulated.push(info);
32
+ }
33
+ if (info && !until?.(id)) {
34
+ const importers = info.importers.concat(info.dynamicImporters);
35
+ for (const imp of importers) {
36
+ if (!seen.has(imp)) {
37
+ getParentModuleInfos(imp, ctx, until, seen, accumulated);
38
+ }
39
+ }
40
+ }
41
+ return accumulated;
26
42
  }
27
43
  function moduleIsTopLevelPage(info) {
28
44
  return info.importers[0]?.includes(ASTRO_PAGE_RESOLVED_MODULE_ID) || info.dynamicImporters[0]?.includes(ASTRO_PAGE_RESOLVED_MODULE_ID);
29
45
  }
30
- function* getTopLevelPages(id, ctx) {
31
- for (const res of walkParentInfos(id, ctx)) {
32
- if (moduleIsTopLevelPage(res[0])) {
33
- yield res;
34
- }
35
- }
46
+ function getTopLevelPageModuleInfos(id, ctx) {
47
+ return getParentModuleInfos(id, ctx).filter(moduleIsTopLevelPage);
36
48
  }
37
49
  export {
38
- getTopLevelPages,
39
- moduleIsTopLevelPage,
40
- walkParentInfos
50
+ getParentExtendedModuleInfos,
51
+ getParentModuleInfos,
52
+ getTopLevelPageModuleInfos,
53
+ moduleIsTopLevelPage
41
54
  };
@@ -1,6 +1,10 @@
1
1
  import { PROPAGATED_ASSET_FLAG } from "../../../content/consts.js";
2
2
  import { prependForwardSlash } from "../../../core/path.js";
3
- import { getTopLevelPages, moduleIsTopLevelPage, walkParentInfos } from "../graph.js";
3
+ import {
4
+ getParentModuleInfos,
5
+ getTopLevelPageModuleInfos,
6
+ moduleIsTopLevelPage
7
+ } from "../graph.js";
4
8
  import { getPageDataByViteID, trackClientOnlyPageDatas } from "../internal.js";
5
9
  function isPropagatedAsset(id) {
6
10
  try {
@@ -21,11 +25,9 @@ function vitePluginAnalyzer(options, internals) {
21
25
  hoistedScripts.add(hid);
22
26
  }
23
27
  if (hoistedScripts.size) {
24
- for (const [parentInfo] of walkParentInfos(from, this, function until(importer) {
25
- return isPropagatedAsset(importer);
26
- })) {
28
+ for (const parentInfo of getParentModuleInfos(from, this, isPropagatedAsset)) {
27
29
  if (isPropagatedAsset(parentInfo.id)) {
28
- for (const [nestedParentInfo] of walkParentInfos(from, this)) {
30
+ for (const nestedParentInfo of getParentModuleInfos(from, this)) {
29
31
  if (moduleIsTopLevelPage(nestedParentInfo)) {
30
32
  for (const hid of hoistedScripts) {
31
33
  if (!pageScripts.has(nestedParentInfo.id)) {
@@ -131,7 +133,7 @@ function vitePluginAnalyzer(options, internals) {
131
133
  clientOnlys.push(resolvedId.id);
132
134
  }
133
135
  }
134
- for (const [pageInfo] of getTopLevelPages(id, this)) {
136
+ for (const pageInfo of getTopLevelPageModuleInfos(id, this)) {
135
137
  const newPageData = getPageDataByViteID(internals, pageInfo.id);
136
138
  if (!newPageData)
137
139
  continue;
@@ -1,7 +1,11 @@
1
1
  import { isBuildableCSSRequest } from "../../../vite-plugin-astro-server/util.js";
2
2
  import { PROPAGATED_ASSET_FLAG } from "../../../content/consts.js";
3
3
  import * as assetName from "../css-asset-name.js";
4
- import { moduleIsTopLevelPage, walkParentInfos } from "../graph.js";
4
+ import {
5
+ getParentExtendedModuleInfos,
6
+ getParentModuleInfos,
7
+ moduleIsTopLevelPage
8
+ } from "../graph.js";
5
9
  import {
6
10
  eachPageData,
7
11
  getPageDataByViteID,
@@ -46,9 +50,8 @@ function rollupPluginAstroBuildCSS(options) {
46
50
  if (options.target === "client") {
47
51
  return internals.cssModuleToChunkIdMap.get(id);
48
52
  }
49
- for (const [pageInfo] of walkParentInfos(id, {
50
- getModuleInfo: meta.getModuleInfo
51
- })) {
53
+ const ctx = { getModuleInfo: meta.getModuleInfo };
54
+ for (const pageInfo of getParentModuleInfos(id, ctx)) {
52
55
  if (new URL(pageInfo.id, "file://").searchParams.has(PROPAGATED_ASSET_FLAG)) {
53
56
  const chunkId2 = assetName.createNameHash(id, [id]);
54
57
  internals.cssModuleToChunkIdMap.set(id, chunkId2);
@@ -87,7 +90,7 @@ function rollupPluginAstroBuildCSS(options) {
87
90
  }
88
91
  }
89
92
  for (const id of Object.keys(chunk.modules)) {
90
- for (const [pageInfo, depth, order] of walkParentInfos(
93
+ for (const { info: pageInfo, depth, order } of getParentExtendedModuleInfos(
91
94
  id,
92
95
  this,
93
96
  function until(importer) {
@@ -95,8 +98,7 @@ function rollupPluginAstroBuildCSS(options) {
95
98
  }
96
99
  )) {
97
100
  if (new URL(pageInfo.id, "file://").searchParams.has(PROPAGATED_ASSET_FLAG)) {
98
- for (const parent of walkParentInfos(id, this)) {
99
- const parentInfo = parent[0];
101
+ for (const parentInfo of getParentModuleInfos(id, this)) {
100
102
  if (moduleIsTopLevelPage(parentInfo) === false)
101
103
  continue;
102
104
  const pageViteID = parentInfo.id;
@@ -216,7 +218,7 @@ function rollupPluginAstroBuildCSS(options) {
216
218
  return [cssBuildPlugin, cssScopeToPlugin, singleCssPlugin, inlineStylesheetsPlugin];
217
219
  }
218
220
  function* getParentClientOnlys(id, ctx, internals) {
219
- for (const [info] of walkParentInfos(id, ctx)) {
221
+ for (const info of getParentModuleInfos(id, ctx)) {
220
222
  yield* getPageDatasByClientOnlyID(internals, info.id);
221
223
  }
222
224
  }
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "4.5.8";
1
+ const ASTRO_VERSION = "4.5.10";
2
2
  const REROUTE_DIRECTIVE_HEADER = "X-Astro-Reroute";
3
3
  const ROUTE_TYPE_HEADER = "X-Astro-Route-Type";
4
4
  const DEFAULT_404_COMPONENT = "astro-default-404";
@@ -23,7 +23,7 @@ async function dev(inlineConfig) {
23
23
  base: restart.container.settings.config.base
24
24
  })
25
25
  );
26
- const currentVersion = "4.5.8";
26
+ const currentVersion = "4.5.10";
27
27
  if (currentVersion.includes("-")) {
28
28
  logger.warn("SKIP_FORMAT", msg.prerelease({ currentVersion }));
29
29
  }
@@ -36,7 +36,7 @@ function serverStart({
36
36
  host,
37
37
  base
38
38
  }) {
39
- const version = "4.5.8";
39
+ const version = "4.5.10";
40
40
  const localPrefix = `${dim("\u2503")} Local `;
41
41
  const networkPrefix = `${dim("\u2503")} Network `;
42
42
  const emptyPrefix = " ".repeat(11);
@@ -261,7 +261,7 @@ function printHelp({
261
261
  message.push(
262
262
  linebreak(),
263
263
  ` ${bgGreen(black(` ${commandName} `))} ${green(
264
- `v${"4.5.8"}`
264
+ `v${"4.5.10"}`
265
265
  )} ${headline}`
266
266
  );
267
267
  }
@@ -9,25 +9,7 @@ import {
9
9
  } from "./index.js";
10
10
  import { renderComponentToString } from "./render/component.js";
11
11
  const ClientOnlyPlaceholder = "astro-client-only";
12
- class Skip {
13
- constructor(vnode) {
14
- this.vnode = vnode;
15
- this.count = 0;
16
- }
17
- count;
18
- increment() {
19
- this.count++;
20
- }
21
- haveNoTried() {
22
- return this.count === 0;
23
- }
24
- isCompleted() {
25
- return this.count > 2;
26
- }
27
- static symbol = Symbol("astro:jsx:skip");
28
- }
29
- let originalConsoleError;
30
- let consoleFilterRefs = 0;
12
+ const hasTriedRenderComponentSymbol = Symbol("hasTriedRenderComponent");
31
13
  async function renderJSX(result, vnode) {
32
14
  switch (true) {
33
15
  case vnode instanceof HTMLString:
@@ -46,19 +28,9 @@ async function renderJSX(result, vnode) {
46
28
  (await Promise.all(vnode.map((v) => renderJSX(result, v)))).join("")
47
29
  );
48
30
  }
49
- let skip;
50
- if (vnode.props) {
51
- if (vnode.props[Skip.symbol]) {
52
- skip = vnode.props[Skip.symbol];
53
- } else {
54
- skip = new Skip(vnode);
55
- }
56
- } else {
57
- skip = new Skip(vnode);
58
- }
59
- return renderJSXVNode(result, vnode, skip);
31
+ return renderJSXVNode(result, vnode);
60
32
  }
61
- async function renderJSXVNode(result, vnode, skip) {
33
+ async function renderJSXVNode(result, vnode) {
62
34
  if (isVNode(vnode)) {
63
35
  switch (true) {
64
36
  case !vnode.type: {
@@ -106,36 +78,20 @@ Did you forget to import the component or is it possible there is a typo?`);
106
78
  _slots.default.push(child);
107
79
  };
108
80
  var extractSlots = extractSlots2;
109
- if (typeof vnode.type === "function" && vnode.type["astro:renderer"]) {
110
- skip.increment();
111
- }
112
81
  if (typeof vnode.type === "function" && vnode.props["server:root"]) {
113
82
  const output2 = await vnode.type(vnode.props ?? {});
114
83
  return await renderJSX(result, output2);
115
84
  }
116
85
  if (typeof vnode.type === "function") {
117
- if (skip.haveNoTried() || skip.isCompleted()) {
118
- useConsoleFilter();
119
- try {
120
- const output2 = await vnode.type(vnode.props ?? {});
121
- let renderResult;
122
- if (output2?.[AstroJSX]) {
123
- renderResult = await renderJSXVNode(result, output2, skip);
124
- return renderResult;
125
- } else if (!output2) {
126
- renderResult = await renderJSXVNode(result, output2, skip);
127
- return renderResult;
128
- }
129
- } catch (e) {
130
- if (skip.isCompleted()) {
131
- throw e;
132
- }
133
- skip.increment();
134
- } finally {
135
- finishUsingConsoleFilter();
86
+ if (vnode.props[hasTriedRenderComponentSymbol]) {
87
+ const output2 = await vnode.type(vnode.props ?? {});
88
+ if (output2?.[AstroJSX] || !output2) {
89
+ return await renderJSXVNode(result, output2);
90
+ } else {
91
+ return;
136
92
  }
137
93
  } else {
138
- skip.increment();
94
+ vnode.props[hasTriedRenderComponentSymbol] = true;
139
95
  }
140
96
  }
141
97
  const { children = null, ...props } = vnode.props ?? {};
@@ -161,7 +117,6 @@ Did you forget to import the component or is it possible there is a typo?`);
161
117
  );
162
118
  }
163
119
  await Promise.all(slotPromises);
164
- props[Skip.symbol] = skip;
165
120
  let output;
166
121
  if (vnode.type === ClientOnlyPlaceholder && vnode.props["client:only"]) {
167
122
  output = await renderComponentToString(
@@ -199,27 +154,6 @@ function prerenderElementChildren(tag, children) {
199
154
  return children;
200
155
  }
201
156
  }
202
- function useConsoleFilter() {
203
- consoleFilterRefs++;
204
- if (!originalConsoleError) {
205
- originalConsoleError = console.error;
206
- try {
207
- console.error = filteredConsoleError;
208
- } catch (error) {
209
- }
210
- }
211
- }
212
- function finishUsingConsoleFilter() {
213
- consoleFilterRefs--;
214
- }
215
- function filteredConsoleError(msg, ...rest) {
216
- if (consoleFilterRefs > 0 && typeof msg === "string") {
217
- const isKnownReactHookError = msg.includes("Warning: Invalid hook call.") && msg.includes("https://reactjs.org/link/invalid-hook-call");
218
- if (isKnownReactHookError)
219
- return;
220
- }
221
- originalConsoleError(msg, ...rest);
222
- }
223
157
  export {
224
158
  renderJSX
225
159
  };
@@ -382,17 +382,15 @@ async function renderComponentToString(result, displayName, Component, props, sl
382
382
  let str = "";
383
383
  let renderedFirstPageChunk = false;
384
384
  let head = "";
385
- if (nonAstroPageNeedsHeadInjection(Component)) {
386
- for (const headChunk of maybeRenderHead()) {
387
- head += chunkToString(result, headChunk);
388
- }
385
+ if (isPage && !result.partial && nonAstroPageNeedsHeadInjection(Component)) {
386
+ head += chunkToString(result, maybeRenderHead());
389
387
  }
390
388
  try {
391
389
  const destination = {
392
390
  write(chunk) {
393
- if (isPage && !renderedFirstPageChunk) {
391
+ if (isPage && !result.partial && !renderedFirstPageChunk) {
394
392
  renderedFirstPageChunk = true;
395
- if (!result.partial && !/<!doctype html/i.test(String(chunk))) {
393
+ if (!/<!doctype html/i.test(String(chunk))) {
396
394
  const doctype = result.compressHTML ? "<!DOCTYPE html>" : "<!DOCTYPE html>\n";
397
395
  str += doctype + head;
398
396
  }
@@ -1,5 +1,5 @@
1
1
  import type { SSRResult } from '../../../@types/astro.js';
2
2
  import type { MaybeRenderHeadInstruction, RenderHeadInstruction } from './instruction.js';
3
3
  export declare function renderAllHeadContent(result: SSRResult): any;
4
- export declare function renderHead(): Generator<RenderHeadInstruction>;
5
- export declare function maybeRenderHead(): Generator<MaybeRenderHeadInstruction>;
4
+ export declare function renderHead(): RenderHeadInstruction;
5
+ export declare function maybeRenderHead(): MaybeRenderHeadInstruction;
@@ -24,11 +24,11 @@ function renderAllHeadContent(result) {
24
24
  }
25
25
  return markHTMLString(content);
26
26
  }
27
- function* renderHead() {
28
- yield createRenderInstruction({ type: "head" });
27
+ function renderHead() {
28
+ return createRenderInstruction({ type: "head" });
29
29
  }
30
- function* maybeRenderHead() {
31
- yield createRenderInstruction({ type: "maybe-head" });
30
+ function maybeRenderHead() {
31
+ return createRenderInstruction({ type: "maybe-head" });
32
32
  }
33
33
  export {
34
34
  maybeRenderHead,
@@ -463,12 +463,11 @@ async function prepareForClientOnlyComponents(newDocument, toLocation) {
463
463
  await hydrationDone(nextPage);
464
464
  const nextHead = nextPage.contentDocument?.head;
465
465
  if (nextHead) {
466
- document.head.querySelectorAll(`style[${PERSIST_ATTR}=""]`).forEach((s) => s.removeAttribute(PERSIST_ATTR));
467
466
  const viteIds = [...nextHead.querySelectorAll(`style[${VITE_ID}]`)].map(
468
467
  (style) => style.getAttribute(VITE_ID)
469
468
  );
470
469
  viteIds.forEach((id) => {
471
- const style = document.head.querySelector(`style[${VITE_ID}="${id}"]`);
470
+ const style = nextHead.querySelector(`style[${VITE_ID}="${id}"]`);
472
471
  if (style && !newDocument.head.querySelector(`style[${VITE_ID}="${id}"]`)) {
473
472
  newDocument.head.appendChild(style.cloneNode(true));
474
473
  }
@@ -1,4 +1,4 @@
1
- import { getTopLevelPages, walkParentInfos } from "../core/build/graph.js";
1
+ import { getParentModuleInfos, getTopLevelPageModuleInfos } from "../core/build/graph.js";
2
2
  import { getAstroMetadata } from "../vite-plugin-astro/index.js";
3
3
  const injectExp = /(?:^\/\/|\/\/!)\s*astro-head-inject/;
4
4
  function configHeadVitePlugin() {
@@ -97,13 +97,13 @@ function astroHeadBuildPlugin(internals) {
97
97
  if (modinfo) {
98
98
  const meta = getAstroMetadata(modinfo);
99
99
  if (meta?.containsHead) {
100
- for (const [pageInfo] of getTopLevelPages(id, this)) {
100
+ for (const pageInfo of getTopLevelPageModuleInfos(id, this)) {
101
101
  let metadata = getOrCreateMetadata(pageInfo.id);
102
102
  metadata.containsHead = true;
103
103
  }
104
104
  }
105
105
  if (meta?.propagation === "self") {
106
- for (const [info] of walkParentInfos(id, this)) {
106
+ for (const info of getParentModuleInfos(id, this)) {
107
107
  let metadata = getOrCreateMetadata(info.id);
108
108
  if (metadata.propagation !== "self") {
109
109
  metadata.propagation = "in-tree";
@@ -112,7 +112,7 @@ function astroHeadBuildPlugin(internals) {
112
112
  }
113
113
  }
114
114
  if (mod.code && injectExp.test(mod.code)) {
115
- for (const [info] of walkParentInfos(id, this)) {
115
+ for (const info of getParentModuleInfos(id, this)) {
116
116
  getOrCreateMetadata(info.id).propagation = "in-tree";
117
117
  }
118
118
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro",
3
- "version": "4.5.8",
3
+ "version": "4.5.10",
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",
@@ -162,8 +162,8 @@
162
162
  "zod": "^3.22.4",
163
163
  "zod-to-json-schema": "^3.22.4",
164
164
  "@astrojs/internal-helpers": "0.3.0",
165
- "@astrojs/markdown-remark": "4.3.1",
166
- "@astrojs/telemetry": "3.0.4"
165
+ "@astrojs/telemetry": "3.0.4",
166
+ "@astrojs/markdown-remark": "4.3.2"
167
167
  },
168
168
  "optionalDependencies": {
169
169
  "sharp": "^0.32.6"
package/types.d.ts CHANGED
@@ -4,6 +4,7 @@ import type { Simplify } from './dist/type-utils.js';
4
4
 
5
5
  /** Any supported HTML or SVG element name, as defined by the HTML specification */
6
6
  export type HTMLTag = keyof astroHTML.JSX.DefinedIntrinsicElements;
7
+
7
8
  /** The built-in attributes for any known HTML or SVG element name */
8
9
  export type HTMLAttributes<Tag extends HTMLTag> = Omit<
9
10
  astroHTML.JSX.IntrinsicElements[Tag],
@@ -15,9 +16,10 @@ export type HTMLAttributes<Tag extends HTMLTag> = Omit<
15
16
  */
16
17
  export type CSSProperty = keyof astroHTML.JSX.KebabCSSDOMProperties;
17
18
 
18
- type PolymorphicAttributes<P extends { as: HTMLTag }> = Omit<P & HTMLAttributes<P['as']>, 'as'> & {
19
+ type PolymorphicAttributes<P extends { as: HTMLTag }> = Omit<P, 'as'> & {
19
20
  as?: P['as'];
20
- };
21
+ } & HTMLAttributes<P['as']>;
22
+
21
23
  export type Polymorphic<P extends { as: HTMLTag }> = PolymorphicAttributes<
22
24
  Omit<P, 'as'> & { as: NonNullable<P['as']> }
23
25
  >;