astro 5.1.4 → 5.1.6

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 (48) hide show
  1. package/astro-jsx.d.ts +3 -1
  2. package/client.d.ts +1 -1
  3. package/dist/actions/runtime/virtual/server.d.ts +1 -1
  4. package/dist/assets/build/generate.d.ts +1 -2
  5. package/dist/assets/build/generate.js +2 -4
  6. package/dist/assets/build/remote.js +1 -1
  7. package/dist/assets/vite-plugin-assets.js +1 -1
  8. package/dist/container/index.js +2 -1
  9. package/dist/content/content-layer.d.ts +1 -1
  10. package/dist/content/content-layer.js +4 -6
  11. package/dist/content/loaders/glob.js +6 -2
  12. package/dist/content/mutable-data-store.d.ts +1 -1
  13. package/dist/content/mutable-data-store.js +25 -13
  14. package/dist/core/build/css-asset-name.js +1 -1
  15. package/dist/core/build/generate.js +3 -1
  16. package/dist/core/build/index.js +3 -2
  17. package/dist/core/compile/compile.js +1 -2
  18. package/dist/core/compile/style.js +2 -1
  19. package/dist/core/constants.js +1 -1
  20. package/dist/core/create-vite.js +4 -4
  21. package/dist/core/dev/container.js +2 -1
  22. package/dist/core/dev/dev.js +5 -7
  23. package/dist/core/errors/dev/utils.js +1 -1
  24. package/dist/core/errors/errors-data.d.ts +2 -0
  25. package/dist/core/errors/errors-data.js +2 -2
  26. package/dist/core/messages.js +2 -2
  27. package/dist/core/middleware/vite-plugin.js +1 -1
  28. package/dist/core/render-context.js +10 -1
  29. package/dist/core/request.d.ts +1 -2
  30. package/dist/core/routing/manifest/create.d.ts +0 -1
  31. package/dist/core/routing/manifest/create.js +2 -21
  32. package/dist/core/routing/manifest/parts.d.ts +2 -0
  33. package/dist/core/routing/manifest/parts.js +22 -0
  34. package/dist/core/routing/manifest/segment.d.ts +1 -0
  35. package/dist/core/routing/manifest/segment.js +22 -0
  36. package/dist/core/server-islands/endpoint.js +1 -1
  37. package/dist/core/sync/index.d.ts +4 -2
  38. package/dist/core/sync/index.js +15 -12
  39. package/dist/env/env-loader.d.ts +2 -2
  40. package/dist/env/env-loader.js +5 -10
  41. package/dist/env/vite-plugin-env.d.ts +1 -2
  42. package/dist/env/vite-plugin-env.js +28 -19
  43. package/dist/{vite-plugin-env/index.d.ts → env/vite-plugin-import-meta-env.d.ts} +2 -2
  44. package/dist/{vite-plugin-env/index.js → env/vite-plugin-import-meta-env.js} +2 -2
  45. package/dist/runtime/server/render/server-islands.js +1 -1
  46. package/dist/vite-plugin-markdown/index.js +1 -1
  47. package/dist/vite-plugin-scanner/index.js +1 -2
  48. package/package.json +5 -1
package/astro-jsx.d.ts CHANGED
@@ -837,10 +837,12 @@ declare namespace astroHTML.JSX {
837
837
 
838
838
  interface LinkHTMLAttributes extends HTMLAttributes {
839
839
  as?: string | undefined | null;
840
+ blocking?: 'render' | undefined | null;
840
841
  crossorigin?: boolean | string | undefined | null;
842
+ disabled?: boolean | undefined | null;
843
+ fetchpriority?: 'auto' | 'high' | 'low' | undefined | null;
841
844
  href?: string | URL | undefined | null;
842
845
  hreflang?: string | undefined | null;
843
- fetchpriority?: 'auto' | 'high' | 'low' | undefined | null;
844
846
  integrity?: string | undefined | null;
845
847
  media?: string | undefined | null;
846
848
  imagesrcset?: string | undefined | null;
package/client.d.ts CHANGED
@@ -110,7 +110,7 @@ declare module '*.avif' {
110
110
  declare module '*.svg' {
111
111
  type Props = {
112
112
  /**
113
- * Accesible, short-text description
113
+ * Accessible, short-text description
114
114
  *
115
115
  * {@link https://developer.mozilla.org/en-US/docs/Web/SVG/Element/title|MDN Reference}
116
116
  */
@@ -26,7 +26,7 @@ export type ActionMiddlewareContext = {
26
26
  calledFrom: 'rpc' | 'form';
27
27
  /** The name of the action. Useful to track the source of an action result during a redirect. */
28
28
  name: string;
29
- /** Programatically call the action to get the result. */
29
+ /** Programmatically call the action to get the result. */
30
30
  handler: () => Promise<SafeResult<any, any>>;
31
31
  };
32
32
  /**
@@ -1,4 +1,3 @@
1
- import type PQueue from 'p-queue';
2
1
  import type { BuildPipeline } from '../../core/build/pipeline.js';
3
2
  import type { Logger } from '../../core/logger/core.js';
4
3
  import type { MapValue } from '../../type-utils.js';
@@ -19,6 +18,6 @@ type AssetEnv = {
19
18
  assetsFolder: AstroConfig['build']['assets'];
20
19
  };
21
20
  export declare function prepareAssetsGenerationEnv(pipeline: BuildPipeline, totalCount: number): Promise<AssetEnv>;
22
- export declare function generateImagesForPath(originalFilePath: string, transformsAndPath: MapValue<AssetsGlobalStaticImagesList>, env: AssetEnv, queue: PQueue): Promise<void>;
21
+ export declare function generateImagesForPath(originalFilePath: string, transformsAndPath: MapValue<AssetsGlobalStaticImagesList>, env: AssetEnv): Promise<void>;
23
22
  export declare function getStaticImageList(): AssetsGlobalStaticImagesList;
24
23
  export {};
@@ -47,12 +47,10 @@ async function prepareAssetsGenerationEnv(pipeline, totalCount) {
47
47
  function getFullImagePath(originalFilePath, env) {
48
48
  return new URL(removeLeadingForwardSlash(originalFilePath), env.serverRoot);
49
49
  }
50
- async function generateImagesForPath(originalFilePath, transformsAndPath, env, queue) {
50
+ async function generateImagesForPath(originalFilePath, transformsAndPath, env) {
51
51
  let originalImage;
52
52
  for (const [_, transform] of transformsAndPath.transforms) {
53
- await queue.add(async () => generateImage(transform.finalPath, transform.transform)).catch((e) => {
54
- throw e;
55
- });
53
+ await generateImage(transform.finalPath, transform.transform);
56
54
  }
57
55
  if (!env.isSSR && transformsAndPath.originalSrcPath && !globalThis.astroAsset.referencedImages?.has(transformsAndPath.originalSrcPath)) {
58
56
  try {
@@ -37,7 +37,7 @@ async function revalidateRemoteImage(src, revalidationData) {
37
37
  webToCachePolicyResponse(
38
38
  res.ok ? res : new Response(null, { status: 200, headers: res.headers })
39
39
  )
40
- // 304 responses themselves are not cachable, so just pretend to get the refreshed TTL
40
+ // 304 responses themselves are not cacheable, so just pretend to get the refreshed TTL
41
41
  );
42
42
  const expires = policy.storable() ? policy.timeToLive() : 0;
43
43
  return {
@@ -1,6 +1,5 @@
1
1
  import { extname } from "node:path";
2
2
  import MagicString from "magic-string";
3
- import { normalizePath } from "vite";
4
3
  import { AstroError, AstroErrorData } from "../core/errors/index.js";
5
4
  import {
6
5
  appendForwardSlash,
@@ -9,6 +8,7 @@ import {
9
8
  removeBase,
10
9
  removeQueryString
11
10
  } from "../core/path.js";
11
+ import { normalizePath } from "../core/viteUtils.js";
12
12
  import { VALID_INPUT_FORMATS, VIRTUAL_MODULE_ID, VIRTUAL_SERVICE_ID } from "./consts.js";
13
13
  import { getAssetsPrefix } from "./utils/getAssetsPrefix.js";
14
14
  import { isESMImportedImage } from "./utils/imageKind.js";
@@ -9,8 +9,9 @@ import { nodeLogDestination } from "../core/logger/node.js";
9
9
  import { NOOP_MIDDLEWARE_FN } from "../core/middleware/noop-middleware.js";
10
10
  import { removeLeadingForwardSlash } from "../core/path.js";
11
11
  import { RenderContext } from "../core/render-context.js";
12
- import { getParts, validateSegment } from "../core/routing/manifest/create.js";
12
+ import { getParts } from "../core/routing/manifest/parts.js";
13
13
  import { getPattern } from "../core/routing/manifest/pattern.js";
14
+ import { validateSegment } from "../core/routing/manifest/segment.js";
14
15
  import { ContainerPipeline } from "./pipeline.js";
15
16
  function createManifest(manifest, renderers, middleware) {
16
17
  function middlewareInstance() {
@@ -40,7 +40,7 @@ export declare function simpleLoader<TData extends {
40
40
  * During development, this is in the `.astro` directory so that the Vite watcher can see it.
41
41
  * In production, it's in the cache directory so that it's preserved between builds.
42
42
  */
43
- export declare function getDataStoreFile(settings: AstroSettings, isDev?: boolean): URL;
43
+ export declare function getDataStoreFile(settings: AstroSettings, isDev: boolean): URL;
44
44
  export declare const globalContentLayer: {
45
45
  init: (options: ContentLayerOptions) => ContentLayer;
46
46
  get: () => ContentLayer | null;
@@ -148,7 +148,7 @@ ${contentConfig.error.message}`);
148
148
  logger.info("Content config changed");
149
149
  shouldClear = true;
150
150
  }
151
- if (previousAstroVersion && previousAstroVersion !== "5.1.4") {
151
+ if (previousAstroVersion && previousAstroVersion !== "5.1.6") {
152
152
  logger.info("Astro version changed");
153
153
  shouldClear = true;
154
154
  }
@@ -156,8 +156,8 @@ ${contentConfig.error.message}`);
156
156
  logger.info("Clearing content store");
157
157
  this.#store.clearAll();
158
158
  }
159
- if ("5.1.4") {
160
- await this.#store.metaStore().set("astro-version", "5.1.4");
159
+ if ("5.1.6") {
160
+ await this.#store.metaStore().set("astro-version", "5.1.6");
161
161
  }
162
162
  if (currentConfigDigest) {
163
163
  await this.#store.metaStore().set("content-config-digest", currentConfigDigest);
@@ -215,8 +215,7 @@ ${contentConfig.error.message}`);
215
215
  );
216
216
  await fs.mkdir(this.#settings.config.cacheDir, { recursive: true });
217
217
  await fs.mkdir(this.#settings.dotAstroDir, { recursive: true });
218
- const cacheFile = getDataStoreFile(this.#settings);
219
- await this.#store.writeToDisk(cacheFile);
218
+ await this.#store.writeToDisk();
220
219
  const assetImportsFile = new URL(ASSET_IMPORTS_FILE, this.#settings.dotAstroDir);
221
220
  await this.#store.writeAssetImports(assetImportsFile);
222
221
  const modulesImportsFile = new URL(MODULES_IMPORTS_FILE, this.#settings.dotAstroDir);
@@ -303,7 +302,6 @@ ${JSON.stringify({ ...raw, id: void 0 }, null, 2)}`
303
302
  });
304
303
  }
305
304
  function getDataStoreFile(settings, isDev) {
306
- isDev ??= process?.env.NODE_ENV === "development";
307
305
  return new URL(DATA_STORE_FILE, isDev ? settings.dotAstroDir : settings.config.cacheDir);
308
306
  }
309
307
  function contentLayerSingleton() {
@@ -44,7 +44,7 @@ function glob(globOptions) {
44
44
  const untouchedEntries = new Set(store.keys());
45
45
  const isLegacy = globOptions._legacy;
46
46
  const emulateLegacyCollections = !config.legacy.collections;
47
- async function syncData(entry, base, entryType) {
47
+ async function syncData(entry, base, entryType, oldId) {
48
48
  if (!entryType) {
49
49
  logger.warn(`No entry type found for ${entry}`);
50
50
  return;
@@ -63,6 +63,9 @@ function glob(globOptions) {
63
63
  fileUrl
64
64
  });
65
65
  const id = generateId({ entry, base, data });
66
+ if (oldId && oldId !== id) {
67
+ store.delete(oldId);
68
+ }
66
69
  let legacyId;
67
70
  if (isLegacy) {
68
71
  const entryURL = new URL(encodeURI(entry), base);
@@ -225,7 +228,8 @@ function glob(globOptions) {
225
228
  }
226
229
  const entryType = configForFile(changedPath);
227
230
  const baseUrl = pathToFileURL(basePath);
228
- await syncData(entry, baseUrl, entryType);
231
+ const oldId = fileToIdMap.get(changedPath);
232
+ await syncData(entry, baseUrl, entryType, oldId);
229
233
  logger.info(`Reloaded data from ${green(entry)}`);
230
234
  }
231
235
  watcher.on("change", onChange);
@@ -21,7 +21,7 @@ export declare class MutableDataStore extends ImmutableDataStore {
21
21
  */
22
22
  metaStore(collectionName?: string): MetaStore;
23
23
  toString(): string;
24
- writeToDisk(filePath: PathLike): Promise<void>;
24
+ writeToDisk(): Promise<void>;
25
25
  /**
26
26
  * Attempts to load a MutableDataStore from the virtual module.
27
27
  * This only works in Vite.
@@ -144,15 +144,15 @@ ${lines.join(",\n")}]);
144
144
  }
145
145
  #saveToDiskDebounced() {
146
146
  this.#dirty = true;
147
- if (this.#file) {
148
- if (this.#saveTimeout) {
149
- clearTimeout(this.#saveTimeout);
150
- }
151
- this.#saveTimeout = setTimeout(() => {
152
- this.#saveTimeout = void 0;
153
- this.writeToDisk(this.#file);
154
- }, SAVE_DEBOUNCE_MS);
147
+ if (this.#saveTimeout) {
148
+ clearTimeout(this.#saveTimeout);
155
149
  }
150
+ this.#saveTimeout = setTimeout(() => {
151
+ this.#saveTimeout = void 0;
152
+ if (this.#file) {
153
+ this.writeToDisk();
154
+ }
155
+ }, SAVE_DEBOUNCE_MS);
156
156
  }
157
157
  #writing = /* @__PURE__ */ new Set();
158
158
  #pending = /* @__PURE__ */ new Set();
@@ -168,6 +168,10 @@ ${lines.join(",\n")}]);
168
168
  this.#writing.add(fileKey);
169
169
  const tempFile = filePath instanceof URL ? new URL(`${filePath.href}.tmp`) : `${filePath}.tmp`;
170
170
  try {
171
+ const oldData = await fs.readFile(filePath, "utf-8").catch(() => "");
172
+ if (oldData === data) {
173
+ return;
174
+ }
171
175
  await fs.writeFile(tempFile, data);
172
176
  await fs.rename(tempFile, filePath);
173
177
  } finally {
@@ -270,13 +274,15 @@ ${lines.join(",\n")}]);
270
274
  toString() {
271
275
  return devalue.stringify(this._collections);
272
276
  }
273
- async writeToDisk(filePath) {
277
+ async writeToDisk() {
274
278
  if (!this.#dirty) {
275
279
  return;
276
280
  }
281
+ if (!this.#file) {
282
+ throw new AstroError(AstroErrorData.UnknownFilesystemError);
283
+ }
277
284
  try {
278
- await this.#writeFileAtomic(filePath, this.toString());
279
- this.#file = filePath;
285
+ await this.#writeFileAtomic(this.#file, this.toString());
280
286
  this.#dirty = false;
281
287
  } catch (err) {
282
288
  throw new AstroError(AstroErrorData.UnknownFilesystemError, { cause: err });
@@ -308,11 +314,17 @@ ${lines.join(",\n")}]);
308
314
  try {
309
315
  if (existsSync(filePath)) {
310
316
  const data = await fs.readFile(filePath, "utf-8");
311
- return MutableDataStore.fromString(data);
317
+ const store2 = await MutableDataStore.fromString(data);
318
+ store2.#file = filePath;
319
+ return store2;
320
+ } else {
321
+ await fs.mkdir(new URL("./", filePath), { recursive: true });
312
322
  }
313
323
  } catch {
314
324
  }
315
- return new MutableDataStore();
325
+ const store = new MutableDataStore();
326
+ store.#file = filePath;
327
+ return store;
316
328
  }
317
329
  }
318
330
  export {
@@ -1,8 +1,8 @@
1
1
  import crypto from "node:crypto";
2
2
  import npath from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
- import { normalizePath } from "vite";
5
4
  import { viteID } from "../util.js";
5
+ import { normalizePath } from "../viteUtils.js";
6
6
  import { getTopLevelPageModuleInfos } from "./graph.js";
7
7
  const confusingBaseNames = ["404", "500"];
8
8
  function shortHashedName(settings) {
@@ -96,7 +96,9 @@ ${bgGreen(black(` ${verb} static routes `))}`);
96
96
  const queue = new PQueue({ concurrency: Math.max(cpuCount, 1) });
97
97
  const assetsTimer = performance.now();
98
98
  for (const [originalPath, transforms] of staticImageList) {
99
- await generateImagesForPath(originalPath, transforms, assetsCreationPipeline, queue);
99
+ queue.add(() => generateImagesForPath(originalPath, transforms, assetsCreationPipeline)).catch((e) => {
100
+ throw e;
101
+ });
100
102
  }
101
103
  await queue.onIdle();
102
104
  const assetsTimeEnd = performance.now();
@@ -33,7 +33,7 @@ async function build(inlineConfig, options = {}) {
33
33
  telemetry.record(eventCliSession("build", userConfig));
34
34
  const settings = await createSettings(astroConfig, fileURLToPath(astroConfig.root));
35
35
  if (inlineConfig.force) {
36
- await clearContentLayerCache({ settings, logger, fs });
36
+ await clearContentLayerCache({ settings, logger, fs, isDev: false });
37
37
  }
38
38
  const builder = new AstroBuilder(settings, {
39
39
  ...options,
@@ -99,7 +99,8 @@ class AstroBuilder {
99
99
  settings: this.settings,
100
100
  logger,
101
101
  fs,
102
- manifest: this.manifest
102
+ manifest: this.manifest,
103
+ command: "build"
103
104
  });
104
105
  return { viteConfig };
105
106
  }
@@ -1,9 +1,8 @@
1
1
  import { fileURLToPath } from "node:url";
2
2
  import { transform } from "@astrojs/compiler";
3
- import { normalizePath } from "vite";
4
3
  import { AggregateError, CompilerError } from "../errors/errors.js";
5
4
  import { AstroErrorData } from "../errors/index.js";
6
- import { resolvePath } from "../viteUtils.js";
5
+ import { normalizePath, resolvePath } from "../viteUtils.js";
7
6
  import { createStylePreprocessor } from "./style.js";
8
7
  async function compile({
9
8
  astroConfig,
@@ -1,6 +1,7 @@
1
1
  import fs from "node:fs";
2
- import { normalizePath, preprocessCSS } from "vite";
2
+ import { preprocessCSS } from "vite";
3
3
  import { AstroErrorData, CSSError, positionAt } from "../errors/index.js";
4
+ import { normalizePath } from "../viteUtils.js";
4
5
  function createStylePreprocessor({
5
6
  filename,
6
7
  viteConfig,
@@ -1,4 +1,4 @@
1
- const ASTRO_VERSION = "5.1.4";
1
+ const ASTRO_VERSION = "5.1.6";
2
2
  const REROUTE_DIRECTIVE_HEADER = "X-Astro-Reroute";
3
3
  const REWRITE_DIRECTIVE_HEADER_KEY = "X-Astro-Rewrite";
4
4
  const REWRITE_DIRECTIVE_HEADER_VALUE = "yes";
@@ -14,6 +14,7 @@ import {
14
14
  } from "../content/index.js";
15
15
  import { createEnvLoader } from "../env/env-loader.js";
16
16
  import { astroEnv } from "../env/vite-plugin-env.js";
17
+ import { importMetaEnv } from "../env/vite-plugin-import-meta-env.js";
17
18
  import astroInternationalization from "../i18n/vite-plugin-i18n.js";
18
19
  import astroPrefetch from "../prefetch/vite-plugin-prefetch.js";
19
20
  import astroDevToolbar from "../toolbar/vite-plugin-dev-toolbar.js";
@@ -22,7 +23,6 @@ import astroPostprocessVitePlugin from "../vite-plugin-astro-postprocess/index.j
22
23
  import { vitePluginAstroServer } from "../vite-plugin-astro-server/index.js";
23
24
  import astroVitePlugin from "../vite-plugin-astro/index.js";
24
25
  import configAliasVitePlugin from "../vite-plugin-config-alias/index.js";
25
- import envVitePlugin from "../vite-plugin-env/index.js";
26
26
  import vitePluginFileURL from "../vite-plugin-fileurl/index.js";
27
27
  import astroHeadPlugin from "../vite-plugin-head/index.js";
28
28
  import astroHmrReloadPlugin from "../vite-plugin-hmr-reload/index.js";
@@ -84,7 +84,7 @@ async function createVite(commandConfig, { settings, logger, mode, command, fs =
84
84
  }
85
85
  });
86
86
  const srcDirPattern = glob.convertPathToPattern(fileURLToPath(settings.config.srcDir));
87
- const envLoader = createEnvLoader();
87
+ const envLoader = createEnvLoader(mode, settings.config);
88
88
  const commonConfig = {
89
89
  // Tell Vite not to combine config from vite.config.js with our provided inline config
90
90
  configFile: false,
@@ -109,8 +109,8 @@ async function createVite(commandConfig, { settings, logger, mode, command, fs =
109
109
  // the build to run very slow as the filewatcher is triggered often.
110
110
  command === "dev" && vitePluginAstroServer({ settings, logger, fs, manifest, ssrManifest }),
111
111
  // ssrManifest is only required in dev mode, where it gets created before a Vite instance is created, and get passed to this function
112
- envVitePlugin({ envLoader }),
113
- astroEnv({ settings, mode, sync, envLoader }),
112
+ importMetaEnv({ envLoader }),
113
+ astroEnv({ settings, sync, envLoader }),
114
114
  markdownVitePlugin({ settings, logger }),
115
115
  htmlVitePlugin(),
116
116
  astroPostprocessVitePlugin(),
@@ -66,7 +66,8 @@ async function createContainer({
66
66
  cleanup: true
67
67
  },
68
68
  force: inlineConfig?.force,
69
- manifest
69
+ manifest,
70
+ command: "dev"
70
71
  });
71
72
  const viteServer = await vite.createServer(viteConfig);
72
73
  const container = {
@@ -1,4 +1,4 @@
1
- import fs, { existsSync } from "node:fs";
1
+ import fs from "node:fs";
2
2
  import { performance } from "node:perf_hooks";
3
3
  import { green } from "kleur/colors";
4
4
  import { gt, major, minor, patch } from "semver";
@@ -22,7 +22,7 @@ async function dev(inlineConfig) {
22
22
  await telemetry.record([]);
23
23
  const restart = await createContainerWithAutomaticRestart({ inlineConfig, fs });
24
24
  const logger = restart.container.logger;
25
- const currentVersion = "5.1.4";
25
+ const currentVersion = "5.1.6";
26
26
  const isPrerelease = currentVersion.includes("-");
27
27
  if (!isPrerelease) {
28
28
  try {
@@ -53,21 +53,19 @@ async function dev(inlineConfig) {
53
53
  let store;
54
54
  try {
55
55
  const dataStoreFile = getDataStoreFile(restart.container.settings, true);
56
- if (existsSync(dataStoreFile)) {
57
- store = await MutableDataStore.fromFile(dataStoreFile);
58
- }
56
+ store = await MutableDataStore.fromFile(dataStoreFile);
59
57
  } catch (err) {
60
58
  logger.error("content", err.message);
61
59
  }
62
60
  if (!store) {
63
- store = new MutableDataStore();
61
+ logger.error("content", "Failed to create data store");
64
62
  }
65
63
  await attachContentServerListeners(restart.container);
66
64
  const config = globalContentConfigObserver.get();
67
65
  if (config.status === "error") {
68
66
  logger.error("content", config.error.message);
69
67
  }
70
- if (config.status === "loaded") {
68
+ if (config.status === "loaded" && store) {
71
69
  const contentLayer = globalContentLayer.init({
72
70
  settings: restart.container.settings,
73
71
  logger,
@@ -4,8 +4,8 @@ import { fileURLToPath } from "node:url";
4
4
  import { stripVTControlCharacters } from "node:util";
5
5
  import { escape } from "html-escaper";
6
6
  import { bold, underline } from "kleur/colors";
7
- import { normalizePath } from "vite";
8
7
  import { removeLeadingForwardSlashWindows } from "../../path.js";
8
+ import { normalizePath } from "../../viteUtils.js";
9
9
  import { AggregateError } from "../errors.js";
10
10
  import { AstroErrorData } from "../index.js";
11
11
  import { codeFrame } from "../printer.js";
@@ -776,6 +776,7 @@ export declare const AstroResponseHeadersReassigned: {
776
776
  };
777
777
  /**
778
778
  * @docs
779
+ * @message Error when initializing session storage with driver `DRIVER`. `ERROR`
779
780
  * @see
780
781
  * - [experimental.session](https://docs.astro.build/en/reference/experimental-flags/sessions/)
781
782
  * @description
@@ -789,6 +790,7 @@ export declare const SessionStorageInitError: {
789
790
  };
790
791
  /**
791
792
  * @docs
793
+ * @message Error when saving session data with driver `DRIVER`. `ERROR`
792
794
  * @see
793
795
  * - [experimental.session](https://docs.astro.build/en/reference/experimental-flags/sessions/)
794
796
  * @description
@@ -278,13 +278,13 @@ const AstroResponseHeadersReassigned = {
278
278
  const SessionStorageInitError = {
279
279
  name: "SessionStorageInitError",
280
280
  title: "Session storage could not be initialized.",
281
- message: (error, driver) => `Error when initializing session storage${driver ? ` with driver ${driver}` : ""}. ${error ?? ""}`,
281
+ message: (error, driver) => `Error when initializing session storage${driver ? ` with driver \`${driver}\`` : ""}. \`${error ?? ""}\``,
282
282
  hint: "For more information, see https://docs.astro.build/en/reference/experimental-flags/sessions/"
283
283
  };
284
284
  const SessionStorageSaveError = {
285
285
  name: "SessionStorageSaveError",
286
286
  title: "Session data could not be saved.",
287
- message: (error, driver) => `Error when saving session data${driver ? ` with driver ${driver}` : ""}. ${error ?? ""}`,
287
+ message: (error, driver) => `Error when saving session data${driver ? ` with driver \`${driver}\`` : ""}. \`${error ?? ""}\``,
288
288
  hint: "For more information, see https://docs.astro.build/en/reference/experimental-flags/sessions/"
289
289
  };
290
290
  const MiddlewareCantBeLoaded = {
@@ -38,7 +38,7 @@ function serverStart({
38
38
  host,
39
39
  base
40
40
  }) {
41
- const version = "5.1.4";
41
+ const version = "5.1.6";
42
42
  const localPrefix = `${dim("\u2503")} Local `;
43
43
  const networkPrefix = `${dim("\u2503")} Network `;
44
44
  const emptyPrefix = " ".repeat(11);
@@ -276,7 +276,7 @@ function printHelp({
276
276
  message.push(
277
277
  linebreak(),
278
278
  ` ${bgGreen(black(` ${commandName} `))} ${green(
279
- `v${"5.1.4"}`
279
+ `v${"5.1.6"}`
280
280
  )} ${headline}`
281
281
  );
282
282
  }
@@ -1,9 +1,9 @@
1
- import { normalizePath } from "vite";
2
1
  import { getOutputDirectory } from "../../prerender/utils.js";
3
2
  import { addRollupInput } from "../build/add-rollup-input.js";
4
3
  import { MIDDLEWARE_PATH_SEGMENT_NAME } from "../constants.js";
5
4
  import { MissingMiddlewareForInternationalization } from "../errors/errors-data.js";
6
5
  import { AstroError } from "../errors/index.js";
6
+ import { normalizePath } from "../viteUtils.js";
7
7
  const MIDDLEWARE_MODULE_ID = "\0astro-internal:middleware";
8
8
  const NOOP_MIDDLEWARE = "\0noop-middleware";
9
9
  function vitePluginMiddleware({ settings }) {
@@ -488,7 +488,16 @@ class RenderContext {
488
488
  computedLocale = computeCurrentLocale(referer, locales, defaultLocale);
489
489
  }
490
490
  } else {
491
- const pathname = routeData.pathname && !isRoute404or500(routeData) ? routeData.pathname : url.pathname;
491
+ let pathname = routeData.pathname;
492
+ if (!routeData.pattern.test(url.pathname)) {
493
+ for (const fallbackRoute of routeData.fallbackRoutes) {
494
+ if (fallbackRoute.pattern.test(url.pathname)) {
495
+ pathname = fallbackRoute.pathname;
496
+ break;
497
+ }
498
+ }
499
+ }
500
+ pathname = pathname && !isRoute404or500(routeData) ? pathname : url.pathname;
492
501
  computedLocale = computeCurrentLocale(pathname, locales, defaultLocale);
493
502
  }
494
503
  this.#currentLocale = computedLocale ?? fallbackTo;
@@ -1,13 +1,12 @@
1
1
  import type { IncomingHttpHeaders } from 'node:http';
2
2
  import type { Logger } from './logger/core.js';
3
3
  type HeaderType = Headers | Record<string, any> | IncomingHttpHeaders;
4
- type RequestBody = ArrayBuffer | Blob | ReadableStream | URLSearchParams | FormData | ReadableStream<Uint8Array>;
5
4
  export interface CreateRequestOptions {
6
5
  url: URL | string;
7
6
  clientAddress?: string | undefined;
8
7
  headers: HeaderType;
9
8
  method?: string;
10
- body?: RequestBody | undefined | null;
9
+ body?: RequestInit['body'];
11
10
  logger: Logger;
12
11
  locals?: object | undefined;
13
12
  /**
@@ -3,7 +3,6 @@ import type { Logger } from '../../logger/core.js';
3
3
  import nodeFs from 'node:fs';
4
4
  import type { RoutePart } from '../../../types/public/internal.js';
5
5
  export declare function getParts(part: string, file: string): RoutePart[];
6
- export declare function validateSegment(segment: string, file?: string): void;
7
6
  export interface CreateRouteManifestParams {
8
7
  /** Astro Settings object */
9
8
  settings: AstroSettings;
@@ -19,14 +19,8 @@ import { routeComparator } from "../priority.js";
19
19
  import { getRouteGenerator } from "./generator.js";
20
20
  import { getPattern } from "./pattern.js";
21
21
  import { getRoutePrerenderOption } from "./prerender.js";
22
+ import { validateSegment } from "./segment.js";
22
23
  const require2 = createRequire(import.meta.url);
23
- function countOccurrences(needle, haystack) {
24
- let count = 0;
25
- for (const hay of haystack) {
26
- if (hay === needle) count += 1;
27
- }
28
- return count;
29
- }
30
24
  const ROUTE_DYNAMIC_SPLIT = /\[(.+?\(.+?\)|.+?)\]/;
31
25
  const ROUTE_SPREAD = /^\.{3}.+$/;
32
26
  function getParts(part, file) {
@@ -46,18 +40,6 @@ function getParts(part, file) {
46
40
  });
47
41
  return result;
48
42
  }
49
- function validateSegment(segment, file = "") {
50
- if (!file) file = segment;
51
- if (segment.includes("][")) {
52
- throw new Error(`Invalid route ${file} \u2014 parameters must be separated`);
53
- }
54
- if (countOccurrences("[", segment) !== countOccurrences("]", segment)) {
55
- throw new Error(`Invalid route ${file} \u2014 brackets are unbalanced`);
56
- }
57
- if ((/.+\[\.\.\.[^\]]+\]/.test(segment) || /\[\.\.\.[^\]]+\].+/.test(segment)) && file.endsWith(".astro")) {
58
- throw new Error(`Invalid route ${file} \u2014 rest parameter must be a standalone segment`);
59
- }
60
- }
61
43
  function isSemanticallyEqualSegment(segmentA, segmentB) {
62
44
  if (segmentA.length !== segmentB.length) {
63
45
  return false;
@@ -529,6 +511,5 @@ function joinSegments(segments) {
529
511
  export {
530
512
  createRouteManifest,
531
513
  getParts,
532
- resolveInjectedRoute,
533
- validateSegment
514
+ resolveInjectedRoute
534
515
  };
@@ -0,0 +1,2 @@
1
+ import type { RoutePart } from '../../../types/public/index.js';
2
+ export declare function getParts(part: string, file: string): RoutePart[];
@@ -0,0 +1,22 @@
1
+ const ROUTE_DYNAMIC_SPLIT = /\[(.+?\(.+?\)|.+?)\]/;
2
+ const ROUTE_SPREAD = /^\.{3}.+$/;
3
+ function getParts(part, file) {
4
+ const result = [];
5
+ part.split(ROUTE_DYNAMIC_SPLIT).map((str, i) => {
6
+ if (!str) return;
7
+ const dynamic = i % 2 === 1;
8
+ const [, content] = dynamic ? /([^(]+)$/.exec(str) || [null, null] : [null, str];
9
+ if (!content || dynamic && !/^(?:\.\.\.)?[\w$]+$/.test(content)) {
10
+ throw new Error(`Invalid route ${file} \u2014 parameter name must match /^[a-zA-Z0-9_$]+$/`);
11
+ }
12
+ result.push({
13
+ content,
14
+ dynamic,
15
+ spread: dynamic && ROUTE_SPREAD.test(content)
16
+ });
17
+ });
18
+ return result;
19
+ }
20
+ export {
21
+ getParts
22
+ };
@@ -0,0 +1 @@
1
+ export declare function validateSegment(segment: string, file?: string): void;
@@ -0,0 +1,22 @@
1
+ function validateSegment(segment, file = "") {
2
+ if (!file) file = segment;
3
+ if (segment.includes("][")) {
4
+ throw new Error(`Invalid route ${file} \u2014 parameters must be separated`);
5
+ }
6
+ if (countOccurrences("[", segment) !== countOccurrences("]", segment)) {
7
+ throw new Error(`Invalid route ${file} \u2014 brackets are unbalanced`);
8
+ }
9
+ if ((/.+\[\.\.\.[^\]]+\]/.test(segment) || /\[\.\.\.[^\]]+\].+/.test(segment)) && file.endsWith(".astro")) {
10
+ throw new Error(`Invalid route ${file} \u2014 rest parameter must be a standalone segment`);
11
+ }
12
+ }
13
+ function countOccurrences(needle, haystack) {
14
+ let count = 0;
15
+ for (const hay of haystack) {
16
+ if (hay === needle) count += 1;
17
+ }
18
+ return count;
19
+ }
20
+ export {
21
+ validateSegment
22
+ };
@@ -93,7 +93,7 @@ function createEndpoint(manifest) {
93
93
  }
94
94
  const key = await manifest.key;
95
95
  const encryptedProps = data.encryptedProps;
96
- const propString = await decryptString(key, encryptedProps);
96
+ const propString = encryptedProps === "" ? "{}" : await decryptString(key, encryptedProps);
97
97
  const props = JSON.parse(propString);
98
98
  const componentModule = await imp();
99
99
  let Component = componentModule[data.componentExport];
@@ -12,6 +12,7 @@ export type SyncOptions = {
12
12
  cleanup?: boolean;
13
13
  };
14
14
  manifest: ManifestData;
15
+ command: 'build' | 'dev' | 'sync';
15
16
  };
16
17
  export default function sync(inlineConfig: AstroInlineConfig, { fs, telemetry: _telemetry }?: {
17
18
  fs?: typeof fsMod;
@@ -20,10 +21,11 @@ export default function sync(inlineConfig: AstroInlineConfig, { fs, telemetry: _
20
21
  /**
21
22
  * Clears the content layer and content collection cache, forcing a full rebuild.
22
23
  */
23
- export declare function clearContentLayerCache({ settings, logger, fs, }: {
24
+ export declare function clearContentLayerCache({ settings, logger, fs, isDev, }: {
24
25
  settings: AstroSettings;
25
26
  logger: Logger;
26
27
  fs?: typeof fsMod;
28
+ isDev: boolean;
27
29
  }): Promise<void>;
28
30
  /**
29
31
  * Generates TypeScript types for all Astro modules. This sets up a `src/env.d.ts` file for type inferencing,
@@ -31,4 +33,4 @@ export declare function clearContentLayerCache({ settings, logger, fs, }: {
31
33
  *
32
34
  * @experimental The JavaScript API is experimental
33
35
  */
34
- export declare function syncInternal({ mode, logger, fs, settings, skip, force, manifest, }: SyncOptions): Promise<void>;
36
+ export declare function syncInternal({ mode, logger, fs, settings, skip, force, manifest, command, }: SyncOptions): Promise<void>;
@@ -1,10 +1,9 @@
1
- import fsMod, { existsSync } from "node:fs";
1
+ import fsMod from "node:fs";
2
2
  import { dirname, relative } from "node:path";
3
3
  import { performance } from "node:perf_hooks";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { dim } from "kleur/colors";
6
6
  import { createServer } from "vite";
7
- import { normalizePath } from "vite";
8
7
  import { CONTENT_TYPES_FILE } from "../../content/consts.js";
9
8
  import { getDataStoreFile, globalContentLayer } from "../../content/content-layer.js";
10
9
  import { createContentTypesGenerator } from "../../content/index.js";
@@ -28,6 +27,7 @@ import {
28
27
  } from "../errors/index.js";
29
28
  import { createRouteManifest } from "../routing/index.js";
30
29
  import { ensureProcessNodeEnv } from "../util.js";
30
+ import { normalizePath } from "../viteUtils.js";
31
31
  async function sync(inlineConfig, { fs, telemetry: _telemetry = false } = {}) {
32
32
  ensureProcessNodeEnv("production");
33
33
  const logger = createNodeLogger(inlineConfig);
@@ -49,15 +49,17 @@ async function sync(inlineConfig, { fs, telemetry: _telemetry = false } = {}) {
49
49
  mode: "production",
50
50
  fs,
51
51
  force: inlineConfig.force,
52
- manifest
52
+ manifest,
53
+ command: "sync"
53
54
  });
54
55
  }
55
56
  async function clearContentLayerCache({
56
57
  settings,
57
58
  logger,
58
- fs = fsMod
59
+ fs = fsMod,
60
+ isDev
59
61
  }) {
60
- const dataStore = getDataStoreFile(settings);
62
+ const dataStore = getDataStoreFile(settings, isDev);
61
63
  if (fs.existsSync(dataStore)) {
62
64
  logger.debug("content", "clearing data store");
63
65
  await fs.promises.rm(dataStore, { force: true });
@@ -71,10 +73,12 @@ async function syncInternal({
71
73
  settings,
72
74
  skip,
73
75
  force,
74
- manifest
76
+ manifest,
77
+ command
75
78
  }) {
79
+ const isDev = command === "dev";
76
80
  if (force) {
77
- await clearContentLayerCache({ settings, logger, fs });
81
+ await clearContentLayerCache({ settings, logger, fs, isDev });
78
82
  }
79
83
  const timerStart = performance.now();
80
84
  if (!skip?.content) {
@@ -82,15 +86,14 @@ async function syncInternal({
82
86
  settings.timer.start("Sync content layer");
83
87
  let store;
84
88
  try {
85
- const dataStoreFile = getDataStoreFile(settings);
86
- if (existsSync(dataStoreFile)) {
87
- store = await MutableDataStore.fromFile(dataStoreFile);
88
- }
89
+ const dataStoreFile = getDataStoreFile(settings, isDev);
90
+ store = await MutableDataStore.fromFile(dataStoreFile);
89
91
  } catch (err) {
90
92
  logger.error("content", err.message);
91
93
  }
92
94
  if (!store) {
93
- store = new MutableDataStore();
95
+ logger.error("content", "Failed to load content store");
96
+ return;
94
97
  }
95
98
  const contentLayer = globalContentLayer.init({
96
99
  settings,
@@ -1,6 +1,6 @@
1
1
  import type { AstroConfig } from '../types/public/index.js';
2
- export declare const createEnvLoader: () => {
3
- load: (mode: string, config: AstroConfig) => Record<string, string>;
2
+ export declare const createEnvLoader: (mode: string, config: AstroConfig) => {
3
+ get: () => Record<string, string>;
4
4
  getPrivateEnv: () => Record<string, string>;
5
5
  };
6
6
  export type EnvLoader = ReturnType<typeof createEnvLoader>;
@@ -27,17 +27,12 @@ function getPrivateEnv(fullEnv, astroConfig) {
27
27
  }
28
28
  return privateEnv;
29
29
  }
30
- const createEnvLoader = () => {
31
- let privateEnv = {};
30
+ const createEnvLoader = (mode, config) => {
31
+ const loaded = loadEnv(mode, config.vite.envDir ?? fileURLToPath(config.root), "");
32
+ const privateEnv = getPrivateEnv(loaded, config);
32
33
  return {
33
- load: (mode, config) => {
34
- const loaded = loadEnv(mode, config.vite.envDir ?? fileURLToPath(config.root), "");
35
- privateEnv = getPrivateEnv(loaded, config);
36
- return loaded;
37
- },
38
- getPrivateEnv: () => {
39
- return privateEnv;
40
- }
34
+ get: () => loaded,
35
+ getPrivateEnv: () => privateEnv
41
36
  };
42
37
  };
43
38
  export {
@@ -3,9 +3,8 @@ import type { AstroSettings } from '../types/astro.js';
3
3
  import type { EnvLoader } from './env-loader.js';
4
4
  interface AstroEnvPluginParams {
5
5
  settings: AstroSettings;
6
- mode: string;
7
6
  sync: boolean;
8
7
  envLoader: EnvLoader;
9
8
  }
10
- export declare function astroEnv({ settings, mode, sync, envLoader }: AstroEnvPluginParams): Plugin;
9
+ export declare function astroEnv({ settings, sync, envLoader }: AstroEnvPluginParams): Plugin;
11
10
  export {};
@@ -7,10 +7,33 @@ import {
7
7
  } from "./constants.js";
8
8
  import { invalidVariablesToError } from "./errors.js";
9
9
  import { getEnvFieldType, validateEnvVariable } from "./validators.js";
10
- function astroEnv({ settings, mode, sync, envLoader }) {
10
+ function astroEnv({ settings, sync, envLoader }) {
11
11
  const { schema, validateSecrets } = settings.config.env;
12
12
  let isDev;
13
13
  let templates = null;
14
+ function ensureTemplateAreLoaded() {
15
+ if (templates !== null) {
16
+ return;
17
+ }
18
+ const loadedEnv = envLoader.get();
19
+ if (!isDev) {
20
+ for (const [key, value] of Object.entries(loadedEnv)) {
21
+ if (value !== void 0) {
22
+ process.env[key] = value;
23
+ }
24
+ }
25
+ }
26
+ const validatedVariables = validatePublicVariables({
27
+ schema,
28
+ loadedEnv,
29
+ validateSecrets,
30
+ sync
31
+ });
32
+ templates = {
33
+ ...getTemplates(schema, validatedVariables, isDev ? loadedEnv : null),
34
+ internal: `export const schema = ${JSON.stringify(schema)};`
35
+ };
36
+ }
14
37
  return {
15
38
  name: "astro-env-plugin",
16
39
  enforce: "pre",
@@ -18,24 +41,7 @@ function astroEnv({ settings, mode, sync, envLoader }) {
18
41
  isDev = command !== "build";
19
42
  },
20
43
  buildStart() {
21
- const loadedEnv = envLoader.load(mode, settings.config);
22
- if (!isDev) {
23
- for (const [key, value] of Object.entries(loadedEnv)) {
24
- if (value !== void 0) {
25
- process.env[key] = value;
26
- }
27
- }
28
- }
29
- const validatedVariables = validatePublicVariables({
30
- schema,
31
- loadedEnv,
32
- validateSecrets,
33
- sync
34
- });
35
- templates = {
36
- ...getTemplates(schema, validatedVariables, isDev ? loadedEnv : null),
37
- internal: `export const schema = ${JSON.stringify(schema)};`
38
- };
44
+ ensureTemplateAreLoaded();
39
45
  },
40
46
  buildEnd() {
41
47
  templates = null;
@@ -47,10 +53,12 @@ function astroEnv({ settings, mode, sync, envLoader }) {
47
53
  },
48
54
  load(id, options) {
49
55
  if (id === resolveVirtualModuleId(VIRTUAL_MODULES_IDS.client)) {
56
+ ensureTemplateAreLoaded();
50
57
  return templates.client;
51
58
  }
52
59
  if (id === resolveVirtualModuleId(VIRTUAL_MODULES_IDS.server)) {
53
60
  if (options?.ssr) {
61
+ ensureTemplateAreLoaded();
54
62
  return templates.server;
55
63
  }
56
64
  throw new AstroError({
@@ -59,6 +67,7 @@ function astroEnv({ settings, mode, sync, envLoader }) {
59
67
  });
60
68
  }
61
69
  if (id === resolveVirtualModuleId(VIRTUAL_MODULES_IDS.internal)) {
70
+ ensureTemplateAreLoaded();
62
71
  return templates.internal;
63
72
  }
64
73
  }
@@ -1,7 +1,7 @@
1
1
  import type * as vite from 'vite';
2
- import type { EnvLoader } from '../env/env-loader.js';
2
+ import type { EnvLoader } from './env-loader.js';
3
3
  interface EnvPluginOptions {
4
4
  envLoader: EnvLoader;
5
5
  }
6
- export default function envVitePlugin({ envLoader }: EnvPluginOptions): vite.Plugin;
6
+ export declare function importMetaEnv({ envLoader }: EnvPluginOptions): vite.Plugin;
7
7
  export {};
@@ -37,7 +37,7 @@ async function replaceDefine(code, id, define, config) {
37
37
  map: result.map || null
38
38
  };
39
39
  }
40
- function envVitePlugin({ envLoader }) {
40
+ function importMetaEnv({ envLoader }) {
41
41
  let privateEnv;
42
42
  let defaultDefines;
43
43
  let isDev;
@@ -108,5 +108,5 @@ function envVitePlugin({ envLoader }) {
108
108
  };
109
109
  }
110
110
  export {
111
- envVitePlugin as default
111
+ importMetaEnv
112
112
  };
@@ -50,7 +50,7 @@ function renderServerIsland(result, _displayName, props, slots) {
50
50
  }
51
51
  }
52
52
  const key = await result.key;
53
- const propsEncrypted = await encryptString(key, JSON.stringify(props));
53
+ const propsEncrypted = Object.keys(props).length === 0 ? "" : await encryptString(key, JSON.stringify(props));
54
54
  const hostId = crypto.randomUUID();
55
55
  const slash = result.base.endsWith("/") ? "" : "/";
56
56
  let serverIslandUrl = `${result.base}${slash}_server-islands/${componentId}${result.trailingSlash === "always" ? "/" : ""}`;
@@ -4,10 +4,10 @@ import {
4
4
  createMarkdownProcessor,
5
5
  isFrontmatterValid
6
6
  } from "@astrojs/markdown-remark";
7
- import { normalizePath } from "vite";
8
7
  import { safeParseFrontmatter } from "../content/utils.js";
9
8
  import { AstroError, AstroErrorData } from "../core/errors/index.js";
10
9
  import { isMarkdownFile, isPage } from "../core/util.js";
10
+ import { normalizePath } from "../core/viteUtils.js";
11
11
  import { shorthash } from "../runtime/server/shorthash.js";
12
12
  import { createDefaultAstroMetadata } from "../vite-plugin-astro/metadata.js";
13
13
  import { getFileInfo } from "../vite-plugin-utils/index.js";
@@ -1,11 +1,10 @@
1
1
  import { extname } from "node:path";
2
2
  import { fileURLToPath } from "node:url";
3
3
  import { bold } from "kleur/colors";
4
- import { normalizePath } from "vite";
5
4
  import { warnMissingAdapter } from "../core/dev/adapter-validation.js";
6
5
  import { getRoutePrerenderOption } from "../core/routing/manifest/prerender.js";
7
6
  import { isEndpoint, isPage } from "../core/util.js";
8
- import { rootRelativePath } from "../core/viteUtils.js";
7
+ import { normalizePath, rootRelativePath } from "../core/viteUtils.js";
9
8
  const KNOWN_FILE_EXTENSIONS = [".astro", ".js", ".ts"];
10
9
  function astroScannerPlugin({
11
10
  settings,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro",
3
- "version": "5.1.4",
3
+ "version": "5.1.6",
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",
@@ -211,6 +211,10 @@
211
211
  "publishConfig": {
212
212
  "provenance": true
213
213
  },
214
+ "funding": {
215
+ "type": "opencollective",
216
+ "url": "https://opencollective.com/astrodotbuild"
217
+ },
214
218
  "scripts": {
215
219
  "prebuild": "astro-scripts prebuild --to-string \"src/runtime/server/astro-island.ts\" \"src/runtime/client/{idle,load,media,only,visible}.ts\"",
216
220
  "build": "pnpm run prebuild && astro-scripts build \"src/**/*.{ts,js}\" --copy-wasm && tsc",