astro 6.0.8 → 6.1.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.
Files changed (89) hide show
  1. package/client.d.ts +30 -40
  2. package/dist/assets/build/generate.js +17 -19
  3. package/dist/assets/build/remote.d.ts +4 -4
  4. package/dist/assets/build/remote.js +12 -10
  5. package/dist/assets/fonts/infra/dev-font-file-id-generator.js +4 -1
  6. package/dist/assets/fonts/vite-plugin-fonts.js +8 -0
  7. package/dist/assets/services/sharp.d.ts +21 -2
  8. package/dist/assets/services/sharp.js +54 -12
  9. package/dist/assets/vite-plugin-assets.js +4 -1
  10. package/dist/cli/add/index.js +55 -1
  11. package/dist/cli/infra/build-time-astro-version-provider.js +1 -1
  12. package/dist/content/content-layer.js +3 -3
  13. package/dist/content/index.d.ts +1 -1
  14. package/dist/content/index.js +2 -3
  15. package/dist/content/runtime.d.ts +2 -0
  16. package/dist/content/runtime.js +2 -1
  17. package/dist/content/types-generator.js +4 -0
  18. package/dist/content/utils.d.ts +0 -1
  19. package/dist/content/utils.js +1 -10
  20. package/dist/core/app/dev/app.d.ts +5 -0
  21. package/dist/core/app/dev/app.js +7 -0
  22. package/dist/core/app/entrypoints/virtual/dev.js +4 -0
  23. package/dist/core/app/node.js +5 -4
  24. package/dist/core/app/validate-headers.d.ts +6 -0
  25. package/dist/core/app/validate-headers.js +4 -0
  26. package/dist/core/base-pipeline.d.ts +5 -0
  27. package/dist/core/base-pipeline.js +7 -0
  28. package/dist/core/build/generate.d.ts +47 -0
  29. package/dist/core/build/generate.js +43 -25
  30. package/dist/core/build/plugins/plugin-css.js +8 -4
  31. package/dist/core/config/schemas/base.d.ts +4 -2
  32. package/dist/core/config/schemas/base.js +22 -1
  33. package/dist/core/config/schemas/relative.d.ts +3 -3
  34. package/dist/core/constants.js +1 -1
  35. package/dist/core/create-vite.js +1 -1
  36. package/dist/core/dev/dev.js +13 -1
  37. package/dist/core/errors/errors-data.d.ts +2 -2
  38. package/dist/core/head-propagation/boundary.d.ts +8 -0
  39. package/dist/core/head-propagation/boundary.js +11 -0
  40. package/dist/core/head-propagation/buffer.d.ts +21 -0
  41. package/dist/core/head-propagation/buffer.js +18 -0
  42. package/dist/core/head-propagation/comment.d.ts +7 -0
  43. package/dist/core/head-propagation/comment.js +7 -0
  44. package/dist/core/head-propagation/graph.d.ts +18 -0
  45. package/dist/core/head-propagation/graph.js +32 -0
  46. package/dist/core/head-propagation/policy.d.ts +22 -0
  47. package/dist/core/head-propagation/policy.js +14 -0
  48. package/dist/core/head-propagation/resolver.d.ts +28 -0
  49. package/dist/core/head-propagation/resolver.js +25 -0
  50. package/dist/core/messages/runtime.d.ts +3 -0
  51. package/dist/core/messages/runtime.js +9 -1
  52. package/dist/core/middleware/vite-plugin.d.ts +1 -1
  53. package/dist/core/middleware/vite-plugin.js +25 -0
  54. package/dist/core/redirects/render.d.ts +17 -0
  55. package/dist/core/redirects/render.js +33 -24
  56. package/dist/core/routing/create-manifest.d.ts +15 -0
  57. package/dist/core/routing/create-manifest.js +131 -130
  58. package/dist/core/routing/prerender.d.ts +5 -0
  59. package/dist/core/routing/prerender.js +7 -1
  60. package/dist/core/server-islands/vite-plugin-server-islands.js +18 -6
  61. package/dist/integrations/hooks.js +4 -1
  62. package/dist/jsx/rehype.js +1 -1
  63. package/dist/manifest/serialized.js +5 -0
  64. package/dist/manifest/virtual-module.d.ts +4 -1
  65. package/dist/manifest/virtual-module.js +37 -35
  66. package/dist/runtime/client/dev-toolbar/apps/audit/rules/a11y.js +15 -5
  67. package/dist/runtime/server/render/astro/factory.js +6 -7
  68. package/dist/runtime/server/render/astro/instance.js +2 -4
  69. package/dist/runtime/server/render/astro/render.js +2 -11
  70. package/dist/runtime/server/render/common.js +3 -2
  71. package/dist/runtime/server/render/head-propagation/runtime.d.ts +20 -0
  72. package/dist/runtime/server/render/head-propagation/runtime.js +53 -0
  73. package/dist/runtime/server/render/page.js +5 -1
  74. package/dist/runtime/server/transition.d.ts +19 -1
  75. package/dist/runtime/server/transition.js +6 -1
  76. package/dist/transitions/events.d.ts +1 -1
  77. package/dist/transitions/events.js +5 -5
  78. package/dist/transitions/router.js +23 -19
  79. package/dist/transitions/swap-functions.js +6 -0
  80. package/dist/types/public/config.d.ts +71 -12
  81. package/dist/types/public/integrations.d.ts +9 -2
  82. package/dist/vite-plugin-app/app.d.ts +5 -0
  83. package/dist/vite-plugin-app/app.js +17 -1
  84. package/dist/vite-plugin-app/createAstroServerApp.js +4 -0
  85. package/dist/vite-plugin-astro-server/plugin.js +2 -1
  86. package/dist/vite-plugin-astro-server/vite.js +2 -2
  87. package/dist/vite-plugin-head/index.js +63 -25
  88. package/dist/vite-plugin-scripts/index.js +5 -0
  89. package/package.json +11 -11
@@ -522,7 +522,10 @@ function toIntegrationResolvedRoute(route, trailingSlash) {
522
522
  type: route.type,
523
523
  pathname: route.pathname,
524
524
  redirect: route.redirect,
525
- redirectRoute: route.redirectRoute ? toIntegrationResolvedRoute(route.redirectRoute, trailingSlash) : void 0
525
+ redirectRoute: route.redirectRoute ? toIntegrationResolvedRoute(route.redirectRoute, trailingSlash) : void 0,
526
+ fallbackRoutes: route.fallbackRoutes.map(
527
+ (fallbackRoute) => toIntegrationResolvedRoute(fallbackRoute, trailingSlash)
528
+ )
526
529
  };
527
530
  }
528
531
  export {
@@ -182,7 +182,7 @@ function addClientOnlyMetadata(node, meta, resolvedPath) {
182
182
  value: node.name
183
183
  });
184
184
  }
185
- if (!attributeNames.includes("client:component-hydpathation")) {
185
+ if (!attributeNames.includes("client:component-path")) {
186
186
  node.attributes.push({
187
187
  type: "mdxJsxAttribute",
188
188
  name: "client:component-path",
@@ -58,6 +58,11 @@ function serializedManifestPlugin({
58
58
  server.watcher.on("unlink", (path) => reloadManifest(path, server));
59
59
  server.watcher.on("change", (path) => reloadManifest(path, server));
60
60
  },
61
+ // Restrict to server environments only since the generated code imports
62
+ // server-only virtual modules (virtual:astro:routes, virtual:astro:pages)
63
+ applyToEnvironment(environment) {
64
+ return environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.astro || environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.ssr || environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.prerender;
65
+ },
61
66
  resolveId: {
62
67
  filter: {
63
68
  id: new RegExp(`^${SERIALIZED_MANIFEST_ID}$`)
@@ -1,2 +1,5 @@
1
1
  import type { Plugin } from 'vite';
2
- export default function virtualModulePlugin(): Plugin;
2
+ import type { AstroSettings } from '../types/astro.js';
3
+ export default function virtualModulePlugin({ settings }: {
4
+ settings: AstroSettings;
5
+ }): Plugin;
@@ -1,11 +1,46 @@
1
1
  import { AstroError, AstroErrorData } from "../core/errors/index.js";
2
2
  import { SERIALIZED_MANIFEST_ID } from "./serialized.js";
3
3
  import { ASTRO_VITE_ENVIRONMENT_NAMES } from "../core/constants.js";
4
+ import { fromRoutingStrategy, toFallbackType, toRoutingStrategy } from "../core/app/common.js";
4
5
  const VIRTUAL_SERVER_ID = "astro:config/server";
5
6
  const RESOLVED_VIRTUAL_SERVER_ID = "\0" + VIRTUAL_SERVER_ID;
6
7
  const VIRTUAL_CLIENT_ID = "astro:config/client";
7
8
  const RESOLVED_VIRTUAL_CLIENT_ID = "\0" + VIRTUAL_CLIENT_ID;
8
- function virtualModulePlugin() {
9
+ function virtualModulePlugin({ settings }) {
10
+ const config = settings.config;
11
+ let i18nCode = "const i18n = undefined;";
12
+ if (config.i18n) {
13
+ const strategy = toRoutingStrategy(config.i18n.routing, config.i18n.domains);
14
+ const fallbackType = toFallbackType(config.i18n.routing);
15
+ const routing = fromRoutingStrategy(strategy, fallbackType);
16
+ i18nCode = `const i18n = {
17
+ defaultLocale: ${JSON.stringify(config.i18n.defaultLocale)},
18
+ locales: ${JSON.stringify(config.i18n.locales)},
19
+ routing: ${JSON.stringify(routing)},
20
+ fallback: ${JSON.stringify(config.i18n.fallback)}
21
+ };`;
22
+ }
23
+ let imageCode = "const image = undefined;";
24
+ if (config.image) {
25
+ imageCode = `const image = {
26
+ objectFit: ${JSON.stringify(config.image.objectFit)},
27
+ objectPosition: ${JSON.stringify(config.image.objectPosition)},
28
+ layout: ${JSON.stringify(config.image.layout)},
29
+ };`;
30
+ }
31
+ const clientConfigCode = `
32
+ ${i18nCode}
33
+ ${imageCode}
34
+ const base = ${JSON.stringify(config.base)};
35
+ const trailingSlash = ${JSON.stringify(config.trailingSlash)};
36
+ const site = ${JSON.stringify(config.site)};
37
+ const compressHTML = ${JSON.stringify(config.compressHTML)};
38
+ const build = {
39
+ format: ${JSON.stringify(config.build.format)},
40
+ };
41
+
42
+ export { base, i18n, trailingSlash, site, compressHTML, build, image };
43
+ `;
9
44
  return {
10
45
  name: "astro-manifest-plugin",
11
46
  resolveId: {
@@ -27,40 +62,7 @@ function virtualModulePlugin() {
27
62
  },
28
63
  handler(id) {
29
64
  if (id === RESOLVED_VIRTUAL_CLIENT_ID) {
30
- const code = `
31
- import { manifest } from '${SERIALIZED_MANIFEST_ID}'
32
- import { fromRoutingStrategy } from 'astro/app';
33
-
34
- let i18n = undefined;
35
- if (manifest.i18n) {
36
- i18n = {
37
- defaultLocale: manifest.i18n.defaultLocale,
38
- locales: manifest.i18n.locales,
39
- routing: fromRoutingStrategy(manifest.i18n.strategy, manifest.i18n.fallbackType),
40
- fallback: manifest.i18n.fallback
41
- };
42
- }
43
-
44
- let image = undefined;
45
- if (manifest.image) {
46
- image = {
47
- objectFit: manifest.image.objectFit,
48
- objectPosition: manifest.image.objectPosition,
49
- layout: manifest.image.layout,
50
- };
51
- }
52
-
53
- const base = manifest.base;
54
- const trailingSlash = manifest.trailingSlash;
55
- const site = manifest.site;
56
- const compressHTML = manifest.compressHTML;
57
- const build = {
58
- format: manifest.buildFormat,
59
- };
60
-
61
- export { base, i18n, trailingSlash, site, compressHTML, build, image };
62
- `;
63
- return { code };
65
+ return { code: clientConfigCode };
64
66
  }
65
67
  if (id === RESOLVED_VIRTUAL_SERVER_ID) {
66
68
  if (this.environment.name === ASTRO_VITE_ENVIRONMENT_NAMES.client) {
@@ -73,6 +73,7 @@ const aria_non_interactive_roles = [
73
73
  "form",
74
74
  "group",
75
75
  "heading",
76
+ "image",
76
77
  "img",
77
78
  "list",
78
79
  "listitem",
@@ -80,7 +81,6 @@ const aria_non_interactive_roles = [
80
81
  "main",
81
82
  "marquee",
82
83
  "math",
83
- "menuitemradio",
84
84
  "navigation",
85
85
  "none",
86
86
  "note",
@@ -133,7 +133,7 @@ const a11y_implicit_semantics = /* @__PURE__ */ new Map([
133
133
  ["h5", "heading"],
134
134
  ["h6", "heading"],
135
135
  ["hr", "separator"],
136
- ["img", "img"],
136
+ ["img", "image"],
137
137
  ["li", "listitem"],
138
138
  ["link", "link"],
139
139
  ["main", "main"],
@@ -181,7 +181,7 @@ const ariaAttributes = new Set(
181
181
  )
182
182
  );
183
183
  const ariaRoles = new Set(
184
- "alert alertdialog application article banner blockquote button caption cell checkbox code columnheader combobox command complementary composite contentinfo definition deletion dialog directory document emphasis feed figure form generic grid gridcell group heading img input insertion landmark link list listbox listitem log main marquee math meter menu menubar menuitem menuitemcheckbox menuitemradio navigation none note option paragraph presentation progressbar radio radiogroup range region roletype row rowgroup rowheader scrollbar search searchbox section sectionhead select separator slider spinbutton status strong structure subscript superscript switch tab table tablist tabpanel term textbox time timer toolbar tooltip tree treegrid treeitem widget window".split(
184
+ "alert alertdialog application article banner blockquote button caption cell checkbox code columnheader combobox command complementary composite contentinfo definition deletion dialog directory document emphasis feed figure form generic grid gridcell group heading image img input insertion landmark link list listbox listitem log main marquee math meter menu menubar menuitem menuitemcheckbox menuitemradio navigation none note option paragraph presentation progressbar radio radiogroup range region roletype row rowgroup rowheader scrollbar search searchbox section sectionhead select separator slider spinbutton status strong structure subscript superscript switch tab table tablist tabpanel term textbox time timer toolbar tooltip tree treegrid treeitem widget window".split(
185
185
  " "
186
186
  )
187
187
  );
@@ -451,7 +451,9 @@ const a11y = [
451
451
  }
452
452
  const elementRoles = role.split(WHITESPACE_REGEX);
453
453
  for (const elementRole of elementRoles) {
454
- const { requiredProps } = roles.get(elementRole);
454
+ const roleData = roles.get(normalizeAriaRole(elementRole));
455
+ if (!roleData) continue;
456
+ const { requiredProps } = roleData;
455
457
  const required_role_props = Object.keys(requiredProps);
456
458
  const missingProps = required_role_props.filter((prop) => !element.hasAttribute(prop));
457
459
  if (missingProps.length > 0) {
@@ -477,7 +479,9 @@ const a11y = [
477
479
  if (!role) return false;
478
480
  const elementRoles = role.split(WHITESPACE_REGEX);
479
481
  for (const elementRole of elementRoles) {
480
- const { props } = roles.get(elementRole);
482
+ const roleData = roles.get(normalizeAriaRole(elementRole));
483
+ if (!roleData) continue;
484
+ const { props } = roleData;
481
485
  const attributes = getAttributeObject(element);
482
486
  const unsupportedAttributes = aria.keys().filter((attribute) => !(attribute in props));
483
487
  const invalidAttributes = Object.keys(attributes).filter(
@@ -546,6 +550,12 @@ function menuitem_implicit_role(attributes) {
546
550
  if (!type) return;
547
551
  return menuitem_type_to_implicit_role.get(type);
548
552
  }
553
+ const ariaQueryRoleAliases = {
554
+ image: "img"
555
+ };
556
+ function normalizeAriaRole(role) {
557
+ return ariaQueryRoleAliases[role] ?? role;
558
+ }
549
559
  function getRole(element) {
550
560
  if (element.hasAttribute("role")) {
551
561
  return element.getAttribute("role");
@@ -1,16 +1,15 @@
1
+ import {
2
+ getPropagationHint as getHint,
3
+ isPropagatingHint
4
+ } from "../../../../core/head-propagation/resolver.js";
1
5
  function isAstroComponentFactory(obj) {
2
6
  return obj == null ? false : obj.isAstroComponentFactory === true;
3
7
  }
4
8
  function isAPropagatingComponent(result, factory) {
5
- const hint = getPropagationHint(result, factory);
6
- return hint === "in-tree" || hint === "self";
9
+ return isPropagatingHint(getPropagationHint(result, factory));
7
10
  }
8
11
  function getPropagationHint(result, factory) {
9
- let hint = factory.propagation || "none";
10
- if (factory.moduleId && result.componentMetadata.has(factory.moduleId) && hint === "none") {
11
- hint = result.componentMetadata.get(factory.moduleId).propagation;
12
- }
13
- return hint;
12
+ return getHint(result, factory);
14
13
  }
15
14
  export {
16
15
  getPropagationHint,
@@ -1,6 +1,6 @@
1
1
  import { isPromise } from "../../util.js";
2
2
  import { renderChild } from "../any.js";
3
- import { isAPropagatingComponent } from "./factory.js";
3
+ import { registerIfPropagating } from "../head-propagation/runtime.js";
4
4
  import { isHeadAndContent } from "./head-and-content.js";
5
5
  const astroComponentInstanceSym = /* @__PURE__ */ Symbol.for("astro.componentInstance");
6
6
  class AstroComponentInstance {
@@ -70,9 +70,7 @@ function validateComponentProps(props, clientDirectives, displayName) {
70
70
  function createAstroComponentInstance(result, displayName, factory, props, slots = {}) {
71
71
  validateComponentProps(props, result.clientDirectives, displayName);
72
72
  const instance = new AstroComponentInstance(result, props, slots, factory);
73
- if (isAPropagatingComponent(result, factory)) {
74
- result._metadata.propagators.add(instance);
75
- }
73
+ registerIfPropagating(result, factory, instance);
76
74
  return instance;
77
75
  }
78
76
  function isAstroComponentInstance(obj) {
@@ -7,6 +7,7 @@ import {
7
7
  encoder
8
8
  } from "../common.js";
9
9
  import { promiseWithResolvers } from "../util.js";
10
+ import { bufferPropagatedHead } from "../head-propagation/runtime.js";
10
11
  import { isHeadAndContent } from "./head-and-content.js";
11
12
  import { isRenderTemplateResult } from "./render-template.js";
12
13
  const DOCTYPE_EXP = /<!doctype html/i;
@@ -122,17 +123,7 @@ async function callComponentAsTemplateResultOrResponse(result, componentFactory,
122
123
  return factoryResult;
123
124
  }
124
125
  async function bufferHeadContent(result) {
125
- const iterator = result._metadata.propagators.values();
126
- while (true) {
127
- const { value, done } = iterator.next();
128
- if (done) {
129
- break;
130
- }
131
- const returnValue = await value.init(result);
132
- if (isHeadAndContent(returnValue) && returnValue.head) {
133
- result._metadata.extraHead.push(returnValue.head);
134
- }
135
- }
126
+ await bufferPropagatedHead(result);
136
127
  }
137
128
  async function renderToAsyncIterable(result, componentFactory, props, children, isPage = false, route) {
138
129
  const templateResult = await callComponentAsTemplateResultOrResponse(
@@ -4,6 +4,7 @@ import {
4
4
  determinesIfNeedsDirectiveScript,
5
5
  getPrescripts
6
6
  } from "../scripts.js";
7
+ import { getInstructionRenderState, shouldRenderInstruction } from "./head-propagation/runtime.js";
7
8
  import { renderAllHeadContent } from "./head.js";
8
9
  import { isRenderInstruction } from "./instruction.js";
9
10
  import { renderServerIslandRuntime } from "./server-islands.js";
@@ -31,13 +32,13 @@ function stringifyChunk(result, chunk) {
31
32
  }
32
33
  }
33
34
  case "head": {
34
- if (result._metadata.hasRenderedHead || result.partial) {
35
+ if (!shouldRenderInstruction("head", getInstructionRenderState(result))) {
35
36
  return "";
36
37
  }
37
38
  return renderAllHeadContent(result);
38
39
  }
39
40
  case "maybe-head": {
40
- if (result._metadata.hasRenderedHead || result._metadata.headInTree || result.partial) {
41
+ if (!shouldRenderInstruction("maybe-head", getInstructionRenderState(result))) {
41
42
  return "";
42
43
  }
43
44
  return renderAllHeadContent(result);
@@ -0,0 +1,20 @@
1
+ import { type HeadInstructionRenderState } from '../../../../core/head-propagation/policy.js';
2
+ import type { SSRResult } from '../../../../types/public/internal.js';
3
+ import type { AstroComponentFactory } from '../astro/factory.js';
4
+ /** Facade helper used by runtime adapters to read effective hint resolution. */
5
+ export declare function getPropagationHint(result: SSRResult, factory: AstroComponentFactory): import("../../../../types/public/internal.js").PropagationHint;
6
+ /**
7
+ * Registers an instance in the propagation set when its hint requires buffering.
8
+ *
9
+ * @example
10
+ * A runtime-created component with `propagation: 'self'` is registered so its
11
+ * styles can be collected before head flush.
12
+ */
13
+ export declare function registerIfPropagating(result: SSRResult, factory: AstroComponentFactory, instance: {
14
+ init(result: SSRResult): unknown | Promise<unknown>;
15
+ }): void;
16
+ export declare function bufferPropagatedHead(result: SSRResult): Promise<void>;
17
+ /** Facade helper for render instruction gating (`head` vs `maybe-head`). */
18
+ export declare function shouldRenderInstruction(type: 'head' | 'maybe-head', state: HeadInstructionRenderState): boolean;
19
+ /** Projects `SSRResult` into the minimal state needed by instruction policy. */
20
+ export declare function getInstructionRenderState(result: SSRResult): HeadInstructionRenderState;
@@ -0,0 +1,53 @@
1
+ import { collectPropagatedHeadParts } from "../../../../core/head-propagation/buffer.js";
2
+ import {
3
+ getPropagationHint as getHint,
4
+ isPropagatingHint
5
+ } from "../../../../core/head-propagation/resolver.js";
6
+ import {
7
+ shouldRenderInstruction as shouldRenderInstructionByPolicy
8
+ } from "../../../../core/head-propagation/policy.js";
9
+ import { isHeadAndContent } from "../astro/head-and-content.js";
10
+ function getPropagationHint(result, factory) {
11
+ return getHint(result, factory);
12
+ }
13
+ function registerIfPropagating(result, factory, instance) {
14
+ if (factory.propagation === "self" || factory.propagation === "in-tree") {
15
+ result._metadata.propagators.add(
16
+ instance
17
+ );
18
+ return;
19
+ }
20
+ if (factory.moduleId) {
21
+ const hint = result.componentMetadata.get(factory.moduleId)?.propagation;
22
+ if (isPropagatingHint(hint ?? "none")) {
23
+ result._metadata.propagators.add(
24
+ instance
25
+ );
26
+ }
27
+ }
28
+ }
29
+ async function bufferPropagatedHead(result) {
30
+ const collected = await collectPropagatedHeadParts({
31
+ propagators: result._metadata.propagators,
32
+ result,
33
+ isHeadAndContent
34
+ });
35
+ result._metadata.extraHead.push(...collected);
36
+ }
37
+ function shouldRenderInstruction(type, state) {
38
+ return shouldRenderInstructionByPolicy(type, state);
39
+ }
40
+ function getInstructionRenderState(result) {
41
+ return {
42
+ hasRenderedHead: result._metadata.hasRenderedHead,
43
+ headInTree: result._metadata.headInTree,
44
+ partial: result.partial
45
+ };
46
+ }
47
+ export {
48
+ bufferPropagatedHead,
49
+ getInstructionRenderState,
50
+ getPropagationHint,
51
+ registerIfPropagating,
52
+ shouldRenderInstruction
53
+ };
@@ -1,6 +1,7 @@
1
1
  import { renderToAsyncIterable, renderToReadableStream, renderToString } from "./astro/render.js";
2
2
  import { encoder } from "./common.js";
3
3
  import { renderComponentToString } from "./component.js";
4
+ import { markHTMLString } from "../escape.js";
4
5
  import { renderCspContent } from "./csp.js";
5
6
  import { isDeno, isNode } from "./util.js";
6
7
  import { isAstroComponentFactory } from "./astro/factory.js";
@@ -13,7 +14,10 @@ async function renderPage(result, componentFactory, props, children, streaming,
13
14
  const pageProps = { ...props ?? {}, "server:root": true };
14
15
  let str;
15
16
  if (result._experimentalQueuedRendering && result._experimentalQueuedRendering.enabled) {
16
- const vnode = await componentFactory(pageProps);
17
+ let vnode = await componentFactory(pageProps);
18
+ if (componentFactory["astro:html"] && typeof vnode === "string") {
19
+ vnode = markHTMLString(vnode);
20
+ }
17
21
  const queue = await buildRenderQueue(
18
22
  vnode,
19
23
  result,
@@ -1,9 +1,27 @@
1
1
  import type { SSRResult } from '../../types/public/internal.js';
2
- import type { TransitionAnimationPair, TransitionAnimationValue } from '../../types/public/view-transitions.js';
2
+ import type { TransitionAnimation, TransitionAnimationPair, TransitionAnimationValue } from '../../types/public/view-transitions.js';
3
3
  export declare function createTransitionScope(result: SSRResult, hash: string): string;
4
+ export declare function reEncode(s: string): string;
4
5
  export declare function renderTransition(result: SSRResult, hash: string, animationName: TransitionAnimationValue | undefined, transitionName: string): string;
5
6
  /** @deprecated This will be removed in Astro 7 */
6
7
  export declare function createAnimationScope(transitionName: string, animations: Record<string, TransitionAnimationPair>): {
7
8
  scope: string;
8
9
  styles: string;
9
10
  };
11
+ export declare class ViewTransitionStyleSheet {
12
+ private scope;
13
+ private name;
14
+ private modern;
15
+ private fallback;
16
+ constructor(scope: string, name: string);
17
+ toString(): string;
18
+ private layer;
19
+ private addRule;
20
+ addAnimationRaw(image: 'old' | 'new' | 'group', animation: string): void;
21
+ addModern(image: 'old' | 'new' | 'group', animation: string): void;
22
+ addFallback(image: 'old' | 'new' | 'group', animation: string): void;
23
+ addAnimationPair(direction: 'forwards' | 'backwards' | string, image: 'old' | 'new', rules: TransitionAnimation | TransitionAnimation[]): void;
24
+ }
25
+ export declare function stringifyAnimation(anim: TransitionAnimation | TransitionAnimation[]): string;
26
+ export declare function stringifyAnimations(anims: TransitionAnimation[]): string;
27
+ export declare function toTimeValue(num: number | string): string;
@@ -174,7 +174,12 @@ function toTimeValue(num) {
174
174
  return typeof num === "number" ? num + "ms" : num;
175
175
  }
176
176
  export {
177
+ ViewTransitionStyleSheet,
177
178
  createAnimationScope,
178
179
  createTransitionScope,
179
- renderTransition
180
+ reEncode,
181
+ renderTransition,
182
+ stringifyAnimation,
183
+ stringifyAnimations,
184
+ toTimeValue
180
185
  };
@@ -9,7 +9,7 @@ export declare const TRANSITION_BEFORE_SWAP = "astro:before-swap";
9
9
  export declare const TRANSITION_AFTER_SWAP = "astro:after-swap";
10
10
  /** @deprecated This will be removed in Astro 7 */
11
11
  export declare const TRANSITION_PAGE_LOAD = "astro:page-load";
12
- type Events = typeof TRANSITION_AFTER_PREPARATION | typeof TRANSITION_AFTER_SWAP | typeof TRANSITION_PAGE_LOAD;
12
+ type Events = 'astro:after-preparation' | 'astro:after-swap' | 'astro:page-load';
13
13
  export declare const triggerEvent: (name: Events) => boolean;
14
14
  export declare const onPageLoad: () => boolean;
15
15
  declare class BeforeEvent extends Event {
@@ -5,7 +5,7 @@ const TRANSITION_BEFORE_SWAP = "astro:before-swap";
5
5
  const TRANSITION_AFTER_SWAP = "astro:after-swap";
6
6
  const TRANSITION_PAGE_LOAD = "astro:page-load";
7
7
  const triggerEvent = (name) => document.dispatchEvent(new Event(name));
8
- const onPageLoad = () => triggerEvent(TRANSITION_PAGE_LOAD);
8
+ const onPageLoad = () => triggerEvent("astro:page-load");
9
9
  class BeforeEvent extends Event {
10
10
  from;
11
11
  to;
@@ -43,7 +43,7 @@ class TransitionBeforePreparationEvent extends BeforeEvent {
43
43
  loader;
44
44
  constructor(from, to, direction, navigationType, sourceElement, info, newDocument, signal, formData, loader) {
45
45
  super(
46
- TRANSITION_BEFORE_PREPARATION,
46
+ "astro:before-preparation",
47
47
  { cancelable: true },
48
48
  from,
49
49
  to,
@@ -62,14 +62,14 @@ class TransitionBeforePreparationEvent extends BeforeEvent {
62
62
  });
63
63
  }
64
64
  }
65
- const isTransitionBeforeSwapEvent = (value) => value.type === TRANSITION_BEFORE_SWAP;
65
+ const isTransitionBeforeSwapEvent = (value) => value.type === "astro:before-swap";
66
66
  class TransitionBeforeSwapEvent extends BeforeEvent {
67
67
  direction;
68
68
  viewTransition;
69
69
  swap;
70
70
  constructor(afterPreparation, viewTransition) {
71
71
  super(
72
- TRANSITION_BEFORE_SWAP,
72
+ "astro:before-swap",
73
73
  void 0,
74
74
  afterPreparation.from,
75
75
  afterPreparation.to,
@@ -106,7 +106,7 @@ async function doPreparation(from, to, direction, navigationType, sourceElement,
106
106
  if (document.dispatchEvent(event)) {
107
107
  await event.loader();
108
108
  if (!event.defaultPrevented) {
109
- triggerEvent(TRANSITION_AFTER_PREPARATION);
109
+ triggerEvent("astro:after-preparation");
110
110
  if (event.navigationType !== "traverse") {
111
111
  updateScrollPosition({ scrollX, scrollY });
112
112
  }
@@ -1,12 +1,5 @@
1
1
  import { internalFetchHeaders } from "virtual:astro:adapter-config/client";
2
- import {
3
- doPreparation,
4
- doSwap,
5
- TRANSITION_AFTER_SWAP,
6
- onPageLoad,
7
- triggerEvent,
8
- updateScrollPosition
9
- } from "./events.js";
2
+ import { doPreparation, doSwap, onPageLoad, triggerEvent, updateScrollPosition } from "./events.js";
10
3
  import { detectScriptExecuted } from "./swap-functions.js";
11
4
  const inBrowser = import.meta.env.SSR === false;
12
5
  const supportsViewTransitions = inBrowser && !!document.startViewTransition;
@@ -212,13 +205,11 @@ async function updateDOM(preparationEvent, options, currentTransition, historySt
212
205
  animateFallbackOld
213
206
  );
214
207
  moveToLocation(swapEvent.to, swapEvent.from, options, pageTitleForBrowserHistory, historyState);
215
- triggerEvent(TRANSITION_AFTER_SWAP);
216
- if (fallback === "animate") {
217
- if (!currentTransition.transitionSkipped && !swapEvent.signal.aborted) {
218
- animate("new").finally(() => currentTransition.viewTransitionFinished());
219
- } else {
220
- currentTransition.viewTransitionFinished();
221
- }
208
+ triggerEvent("astro:after-swap");
209
+ if (fallback === "animate" && !currentTransition.transitionSkipped && !swapEvent.signal.aborted) {
210
+ animate("new").finally(() => currentTransition.viewTransitionFinished());
211
+ } else {
212
+ currentTransition.viewTransitionFinished?.();
222
213
  }
223
214
  }
224
215
  function abortAndRecreateMostRecentNavigation() {
@@ -227,7 +218,7 @@ function abortAndRecreateMostRecentNavigation() {
227
218
  controller: new AbortController()
228
219
  };
229
220
  }
230
- async function transition(direction, from, to, options, historyState) {
221
+ async function transition(direction, from, to, options, historyState, hasUAVisualTransition = false) {
231
222
  const currentNavigation = abortAndRecreateMostRecentNavigation();
232
223
  if (!transitionEnabledOnThisPage() || location.origin !== to.origin) {
233
224
  if (currentNavigation === mostRecentNavigation) mostRecentNavigation = void 0;
@@ -323,14 +314,20 @@ async function transition(direction, from, to, options, historyState) {
323
314
  return;
324
315
  }
325
316
  document.documentElement.setAttribute(DIRECTION_ATTR, prepEvent.direction);
326
- if (supportsViewTransitions) {
317
+ if (supportsViewTransitions && !hasUAVisualTransition) {
327
318
  currentTransition.viewTransition = document.startViewTransition(
328
319
  async () => await updateDOM(prepEvent, options, currentTransition, historyState)
329
320
  );
330
321
  } else {
331
322
  const updateDone = (async () => {
332
323
  await Promise.resolve();
333
- await updateDOM(prepEvent, options, currentTransition, historyState, getFallback());
324
+ await updateDOM(
325
+ prepEvent,
326
+ options,
327
+ currentTransition,
328
+ historyState,
329
+ hasUAVisualTransition ? "swap" : getFallback()
330
+ );
334
331
  return void 0;
335
332
  })();
336
333
  currentTransition.viewTransition = {
@@ -396,7 +393,14 @@ function onPopState(ev) {
396
393
  const nextIndex = state.index;
397
394
  const direction = nextIndex > currentHistoryIndex ? "forward" : "back";
398
395
  currentHistoryIndex = nextIndex;
399
- transition(direction, originalLocation, new URL(location.href), {}, state);
396
+ transition(
397
+ direction,
398
+ originalLocation,
399
+ new URL(location.href),
400
+ {},
401
+ state,
402
+ ev.hasUAVisualTransition
403
+ );
400
404
  }
401
405
  const onScrollEnd = () => {
402
406
  if (history.state && (scrollX !== history.state.scrollX || scrollY !== history.state.scrollY)) {
@@ -116,6 +116,12 @@ const persistedHeadElement = (el, newDoc) => {
116
116
  const href = el.getAttribute("href");
117
117
  return newDoc.head.querySelector(`link[rel=stylesheet][href="${href}"]`);
118
118
  }
119
+ if (import.meta.env.DEV && el.tagName === "STYLE") {
120
+ const viteDevId = el.getAttribute("data-vite-dev-id");
121
+ if (viteDevId) {
122
+ return newDoc.head.querySelector(`style[data-vite-dev-id="${viteDevId}"]`);
123
+ }
124
+ }
119
125
  if (el.tagName === "STYLE" && el.textContent) {
120
126
  const styles = newDoc.head.querySelectorAll("style");
121
127
  for (const s of styles) {