nuxt-nightly 4.2.0-29331207.25e91a2b → 4.2.0-29331232.6f9cb0d2

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.
@@ -3,6 +3,9 @@ import type { NuxtApp } from '../nuxt.js';
3
3
  import type { NuxtError } from './error.js';
4
4
  export type AsyncDataRequestStatus = 'idle' | 'pending' | 'success' | 'error';
5
5
  export type _Transform<Input = any, Output = any> = (input: Input) => Output | Promise<Output>;
6
+ export type AsyncDataHandler<ResT> = (nuxtApp: NuxtApp, options: {
7
+ signal: AbortSignal;
8
+ }) => Promise<ResT>;
6
9
  export type PickFrom<T, K extends Array<string>> = T extends Array<any> ? T : T extends Record<string, any> ? keyof T extends K[number] ? T : K[number] extends never ? T : Pick<T, K[number]> : T;
7
10
  export type KeysOf<T> = Array<T extends T ? keyof T extends string ? keyof T : never : never>;
8
11
  export type KeyOfRes<Transform extends _Transform> = KeysOf<ReturnType<Transform>>;
@@ -60,6 +63,10 @@ export interface AsyncDataOptions<ResT, DataT = ResT, PickKeys extends KeysOf<Da
60
63
  * @default 'cancel'
61
64
  */
62
65
  dedupe?: 'cancel' | 'defer';
66
+ /**
67
+ * A timeout in milliseconds after which the request will be aborted if it has not resolved yet.
68
+ */
69
+ timeout?: number;
63
70
  }
64
71
  export interface AsyncDataExecuteOptions {
65
72
  /**
@@ -71,6 +78,8 @@ export interface AsyncDataExecuteOptions {
71
78
  cause?: AsyncDataRefreshCause;
72
79
  /** @internal */
73
80
  cachedData?: any;
81
+ signal?: AbortSignal;
82
+ timeout?: number;
74
83
  }
75
84
  export interface _AsyncData<DataT, ErrorT> {
76
85
  data: Ref<DataT>;
@@ -89,8 +98,8 @@ export type AsyncData<Data, Error> = _AsyncData<Data, Error> & Promise<_AsyncDat
89
98
  * @param handler An asynchronous function that must return a truthy value (for example, it should not be `undefined` or `null`) or the request may be duplicated on the client side.
90
99
  * @param options customize the behavior of useAsyncData
91
100
  */
92
- export declare function useAsyncData<ResT, NuxtErrorDataT = unknown, DataT = ResT, PickKeys extends KeysOf<DataT> = KeysOf<DataT>, DefaultT = undefined>(handler: (ctx?: NuxtApp) => Promise<ResT>, options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | undefined>;
93
- export declare function useAsyncData<ResT, NuxtErrorDataT = unknown, DataT = ResT, PickKeys extends KeysOf<DataT> = KeysOf<DataT>, DefaultT = DataT>(handler: (ctx?: NuxtApp) => Promise<ResT>, options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | undefined>;
101
+ export declare function useAsyncData<ResT, NuxtErrorDataT = unknown, DataT = ResT, PickKeys extends KeysOf<DataT> = KeysOf<DataT>, DefaultT = undefined>(handler: AsyncDataHandler<ResT>, options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | undefined>;
102
+ export declare function useAsyncData<ResT, NuxtErrorDataT = unknown, DataT = ResT, PickKeys extends KeysOf<DataT> = KeysOf<DataT>, DefaultT = DataT>(handler: AsyncDataHandler<ResT>, options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | undefined>;
94
103
  /**
95
104
  * Provides access to data that resolves asynchronously in an SSR-friendly composable.
96
105
  * See {@link https://nuxt.com/docs/4.x/api/composables/use-async-data}
@@ -98,8 +107,8 @@ export declare function useAsyncData<ResT, NuxtErrorDataT = unknown, DataT = Res
98
107
  * @param handler An asynchronous function that must return a truthy value (for example, it should not be `undefined` or `null`) or the request may be duplicated on the client side.
99
108
  * @param options customize the behavior of useAsyncData
100
109
  */
101
- export declare function useAsyncData<ResT, NuxtErrorDataT = unknown, DataT = ResT, PickKeys extends KeysOf<DataT> = KeysOf<DataT>, DefaultT = undefined>(key: MaybeRefOrGetter<string>, handler: (ctx?: NuxtApp) => Promise<ResT>, options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | undefined>;
102
- export declare function useAsyncData<ResT, NuxtErrorDataT = unknown, DataT = ResT, PickKeys extends KeysOf<DataT> = KeysOf<DataT>, DefaultT = DataT>(key: MaybeRefOrGetter<string>, handler: (ctx?: NuxtApp) => Promise<ResT>, options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | undefined>;
110
+ export declare function useAsyncData<ResT, NuxtErrorDataT = unknown, DataT = ResT, PickKeys extends KeysOf<DataT> = KeysOf<DataT>, DefaultT = undefined>(key: MaybeRefOrGetter<string>, handler: AsyncDataHandler<ResT>, options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | undefined>;
111
+ export declare function useAsyncData<ResT, NuxtErrorDataT = unknown, DataT = ResT, PickKeys extends KeysOf<DataT> = KeysOf<DataT>, DefaultT = DataT>(key: MaybeRefOrGetter<string>, handler: AsyncDataHandler<ResT>, options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | undefined>;
103
112
  /**
104
113
  * Provides access to data that resolves asynchronously in an SSR-friendly composable.
105
114
  * See {@link https://nuxt.com/docs/4.x/api/composables/use-lazy-async-data}
@@ -107,8 +116,8 @@ export declare function useAsyncData<ResT, NuxtErrorDataT = unknown, DataT = Res
107
116
  * @param handler An asynchronous function that must return a truthy value (for example, it should not be `undefined` or `null`) or the request may be duplicated on the client side.
108
117
  * @param options customize the behavior of useLazyAsyncData
109
118
  */
110
- export declare function useLazyAsyncData<ResT, NuxtErrorDataT = unknown, DataT = ResT, PickKeys extends KeysOf<DataT> = KeysOf<DataT>, DefaultT = undefined>(handler: (ctx?: NuxtApp) => Promise<ResT>, options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'>): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | undefined>;
111
- export declare function useLazyAsyncData<ResT, NuxtErrorDataT = unknown, DataT = ResT, PickKeys extends KeysOf<DataT> = KeysOf<DataT>, DefaultT = DataT>(handler: (ctx?: NuxtApp) => Promise<ResT>, options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'>): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | undefined>;
119
+ export declare function useLazyAsyncData<ResT, NuxtErrorDataT = unknown, DataT = ResT, PickKeys extends KeysOf<DataT> = KeysOf<DataT>, DefaultT = undefined>(handler: AsyncDataHandler<ResT>, options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'>): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | undefined>;
120
+ export declare function useLazyAsyncData<ResT, NuxtErrorDataT = unknown, DataT = ResT, PickKeys extends KeysOf<DataT> = KeysOf<DataT>, DefaultT = DataT>(handler: AsyncDataHandler<ResT>, options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'>): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | undefined>;
112
121
  /**
113
122
  * Provides access to data that resolves asynchronously in an SSR-friendly composable.
114
123
  * See {@link https://nuxt.com/docs/4.x/api/composables/use-lazy-async-data}
@@ -116,8 +125,8 @@ export declare function useLazyAsyncData<ResT, NuxtErrorDataT = unknown, DataT =
116
125
  * @param handler An asynchronous function that must return a truthy value (for example, it should not be `undefined` or `null`) or the request may be duplicated on the client side.
117
126
  * @param options customize the behavior of useLazyAsyncData
118
127
  */
119
- export declare function useLazyAsyncData<ResT, NuxtErrorDataT = unknown, DataT = ResT, PickKeys extends KeysOf<DataT> = KeysOf<DataT>, DefaultT = undefined>(key: MaybeRefOrGetter<string>, handler: (ctx?: NuxtApp) => Promise<ResT>, options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'>): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | undefined>;
120
- export declare function useLazyAsyncData<ResT, NuxtErrorDataT = unknown, DataT = ResT, PickKeys extends KeysOf<DataT> = KeysOf<DataT>, DefaultT = DataT>(key: MaybeRefOrGetter<string>, handler: (ctx?: NuxtApp) => Promise<ResT>, options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'>): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | undefined>;
128
+ export declare function useLazyAsyncData<ResT, NuxtErrorDataT = unknown, DataT = ResT, PickKeys extends KeysOf<DataT> = KeysOf<DataT>, DefaultT = undefined>(key: MaybeRefOrGetter<string>, handler: AsyncDataHandler<ResT>, options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'>): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | undefined>;
129
+ export declare function useLazyAsyncData<ResT, NuxtErrorDataT = unknown, DataT = ResT, PickKeys extends KeysOf<DataT> = KeysOf<DataT>, DefaultT = DataT>(key: MaybeRefOrGetter<string>, handler: AsyncDataHandler<ResT>, options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'>): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, (NuxtErrorDataT extends Error | NuxtError ? NuxtErrorDataT : NuxtError<NuxtErrorDataT>) | undefined>;
121
130
  /** @since 3.1.0 */
122
131
  export declare function useNuxtData<DataT = any>(key: string): {
123
132
  data: Ref<DataT | undefined>;
@@ -133,4 +142,5 @@ export type CreatedAsyncData<ResT, NuxtErrorDataT = unknown, DataT = ResT, Defau
133
142
  _init: boolean;
134
143
  _deps: number;
135
144
  _execute: (opts?: AsyncDataExecuteOptions) => Promise<void>;
145
+ _abortController?: AbortController;
136
146
  };
@@ -174,7 +174,17 @@ You can use a different key or move the call to a composable to ensure the optio
174
174
  return nuxtApp._asyncData[key.value].execute(...args2);
175
175
  },
176
176
  execute: (...args2) => asyncReturn.refresh(...args2),
177
- clear: () => clearNuxtDataByKey(nuxtApp, key.value)
177
+ clear: () => {
178
+ const entry = nuxtApp._asyncData[key.value];
179
+ if (entry?._abortController) {
180
+ try {
181
+ entry._abortController.abort(new DOMException("AsyncData aborted by user.", "AbortError"));
182
+ } finally {
183
+ entry._abortController = void 0;
184
+ }
185
+ }
186
+ clearNuxtDataByKey(nuxtApp, key.value);
187
+ }
178
188
  };
179
189
  const asyncDataPromise = Promise.resolve(nuxtApp._asyncDataPromises[key.value]).then(() => asyncReturn);
180
190
  Object.assign(asyncDataPromise, asyncReturn);
@@ -280,9 +290,6 @@ function clearNuxtDataByKey(nuxtApp, key) {
280
290
  nuxtApp._asyncData[key].status.value = "idle";
281
291
  }
282
292
  if (key in nuxtApp._asyncDataPromises) {
283
- if (nuxtApp._asyncDataPromises[key]) {
284
- nuxtApp._asyncDataPromises[key].cancelled = true;
285
- }
286
293
  nuxtApp._asyncDataPromises[key] = void 0;
287
294
  }
288
295
  }
@@ -296,13 +303,13 @@ function pick(obj, keys) {
296
303
  function createAsyncData(nuxtApp, key, _handler, options, initialCachedData) {
297
304
  nuxtApp.payload._errors[key] ??= void 0;
298
305
  const hasCustomGetCachedData = options.getCachedData !== getDefaultCachedData;
299
- const handler = import.meta.client || !import.meta.prerender || !nuxtApp.ssrContext?._sharedPrerenderCache ? _handler : () => {
300
- const value = nuxtApp.ssrContext._sharedPrerenderCache.get(key);
306
+ const handler = import.meta.client || !import.meta.prerender || !nuxtApp.ssrContext?._sharedPrerenderCache ? _handler : (nuxtApp2, options2) => {
307
+ const value = nuxtApp2.ssrContext._sharedPrerenderCache.get(key);
301
308
  if (value) {
302
309
  return value;
303
310
  }
304
- const promise = Promise.resolve().then(() => nuxtApp.runWithContext(() => _handler(nuxtApp)));
305
- nuxtApp.ssrContext._sharedPrerenderCache.set(key, promise);
311
+ const promise = Promise.resolve().then(() => nuxtApp2.runWithContext(() => _handler(nuxtApp2, options2)));
312
+ nuxtApp2.ssrContext._sharedPrerenderCache.set(key, promise);
306
313
  return promise;
307
314
  };
308
315
  const _ref = options.deep ? ref : shallowRef;
@@ -327,7 +334,6 @@ function createAsyncData(nuxtApp, key, _handler, options, initialCachedData) {
327
334
  if ((opts.dedupe ?? options.dedupe) === "defer") {
328
335
  return nuxtApp._asyncDataPromises[key];
329
336
  }
330
- nuxtApp._asyncDataPromises[key].cancelled = true;
331
337
  }
332
338
  if (granularCachedData || opts.cause === "initial" || nuxtApp.isHydrating) {
333
339
  const cachedData = "cachedData" in opts ? opts.cachedData : options.getCachedData(key, nuxtApp, { cause: opts.cause ?? "refresh:manual" });
@@ -341,19 +347,31 @@ function createAsyncData(nuxtApp, key, _handler, options, initialCachedData) {
341
347
  if (pendingWhenIdle) {
342
348
  asyncData.pending.value = true;
343
349
  }
350
+ if (asyncData._abortController) {
351
+ asyncData._abortController.abort(new DOMException("AsyncData request cancelled by deduplication", "AbortError"));
352
+ }
353
+ asyncData._abortController = new AbortController();
344
354
  asyncData.status.value = "pending";
345
355
  const promise = new Promise(
346
356
  (resolve, reject) => {
347
357
  try {
348
- resolve(handler(nuxtApp));
358
+ const timeout = opts.timeout ?? options.timeout;
359
+ const mergedSignal = mergeAbortSignals([asyncData._abortController?.signal, opts?.signal], timeout);
360
+ if (mergedSignal.aborted) {
361
+ const reason = mergedSignal.reason;
362
+ reject(reason instanceof Error ? reason : new DOMException(String(reason ?? "Aborted"), "AbortError"));
363
+ return;
364
+ }
365
+ mergedSignal.addEventListener("abort", () => {
366
+ const reason = mergedSignal.reason;
367
+ reject(reason instanceof Error ? reason : new DOMException(String(reason ?? "Aborted"), "AbortError"));
368
+ }, { once: true });
369
+ return Promise.resolve(handler(nuxtApp, { signal: mergedSignal })).then(resolve, reject);
349
370
  } catch (err) {
350
371
  reject(err);
351
372
  }
352
373
  }
353
374
  ).then(async (_result) => {
354
- if (promise.cancelled) {
355
- return nuxtApp._asyncDataPromises[key];
356
- }
357
375
  let result = _result;
358
376
  if (options.transform) {
359
377
  result = await options.transform(_result);
@@ -371,16 +389,20 @@ function createAsyncData(nuxtApp, key, _handler, options, initialCachedData) {
371
389
  asyncData.error.value = void 0;
372
390
  asyncData.status.value = "success";
373
391
  }).catch((error) => {
374
- if (promise.cancelled) {
375
- return nuxtApp._asyncDataPromises[key];
392
+ if (nuxtApp._asyncDataPromises[key] && nuxtApp._asyncDataPromises[key] !== promise) {
393
+ return;
394
+ }
395
+ if (asyncData._abortController?.signal.aborted) {
396
+ return;
397
+ }
398
+ if (typeof DOMException !== "undefined" && error instanceof DOMException && error.name === "AbortError") {
399
+ asyncData.status.value = "idle";
400
+ return;
376
401
  }
377
402
  asyncData.error.value = createError(error);
378
403
  asyncData.data.value = unref(options.default());
379
404
  asyncData.status.value = "error";
380
405
  }).finally(() => {
381
- if (promise.cancelled) {
382
- return;
383
- }
384
406
  if (pendingWhenIdle) {
385
407
  asyncData.pending.value = false;
386
408
  }
@@ -428,3 +450,40 @@ function createHash(_handler, options) {
428
450
  getCachedData: options.getCachedData ? hash(options.getCachedData) : void 0
429
451
  };
430
452
  }
453
+ function mergeAbortSignals(signals, timeout) {
454
+ const list = signals.filter((s) => !!s);
455
+ if (typeof timeout === "number" && timeout >= 0) {
456
+ const timeoutSignal = AbortSignal.timeout?.(timeout);
457
+ if (timeoutSignal) {
458
+ list.push(timeoutSignal);
459
+ }
460
+ }
461
+ if (AbortSignal.any) {
462
+ return AbortSignal.any(list);
463
+ }
464
+ const controller = new AbortController();
465
+ for (const sig of list) {
466
+ if (sig.aborted) {
467
+ const reason = sig.reason ?? new DOMException("Aborted", "AbortError");
468
+ try {
469
+ controller.abort(reason);
470
+ } catch {
471
+ controller.abort();
472
+ }
473
+ return controller.signal;
474
+ }
475
+ }
476
+ const onAbort = () => {
477
+ const abortedSignal = list.find((s) => s.aborted);
478
+ const reason = abortedSignal?.reason ?? new DOMException("Aborted", "AbortError");
479
+ try {
480
+ controller.abort(reason);
481
+ } catch {
482
+ controller.abort();
483
+ }
484
+ };
485
+ for (const sig of list) {
486
+ sig.addEventListener?.("abort", onAbort, { once: true });
487
+ }
488
+ return controller.signal;
489
+ }
@@ -11,7 +11,7 @@ interface NitroFetchOptions<R extends NitroFetchRequest, M extends AvailableRout
11
11
  method?: M;
12
12
  }
13
13
  type ComputedFetchOptions<R extends NitroFetchRequest, M extends AvailableRouterMethod<R>, DataT = any> = ComputedOptions<NitroFetchOptions<R, M, DataT>>;
14
- export interface UseFetchOptions<ResT, DataT = ResT, PickKeys extends KeysOf<DataT> = KeysOf<DataT>, DefaultT = undefined, R extends NitroFetchRequest = string & {}, M extends AvailableRouterMethod<R> = AvailableRouterMethod<R>> extends Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'watch'>, ComputedFetchOptions<R, M, DataT> {
14
+ export interface UseFetchOptions<ResT, DataT = ResT, PickKeys extends KeysOf<DataT> = KeysOf<DataT>, DefaultT = undefined, R extends NitroFetchRequest = string & {}, M extends AvailableRouterMethod<R> = AvailableRouterMethod<R>> extends Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'watch'>, Omit<ComputedFetchOptions<R, M, DataT>, 'timeout'> {
15
15
  key?: MaybeRefOrGetter<string>;
16
16
  $fetch?: typeof globalThis.$fetch;
17
17
  watch?: MultiWatchSources | false;
@@ -22,6 +22,7 @@ export function useFetch(request, arg1, arg2) {
22
22
  getCachedData,
23
23
  deep,
24
24
  dedupe,
25
+ timeout,
25
26
  ...fetchOptions
26
27
  } = opts;
27
28
  const _fetchOptions = reactive({
@@ -39,6 +40,7 @@ export function useFetch(request, arg1, arg2) {
39
40
  getCachedData,
40
41
  deep,
41
42
  dedupe,
43
+ timeout,
42
44
  watch: watchSources === false ? [] : [...watchSources || [], _fetchOptions]
43
45
  };
44
46
  if (import.meta.dev) {
@@ -51,16 +53,7 @@ export function useFetch(request, arg1, arg2) {
51
53
  watch(key, setImmediate, { flush: "sync", once: true });
52
54
  watch([...watchSources || [], _fetchOptions], setImmediate, { flush: "sync", once: true });
53
55
  }
54
- let controller;
55
- const asyncData = useAsyncData(watchSources === false ? key.value : key, () => {
56
- controller?.abort?.(new DOMException("Request aborted as another request to the same endpoint was initiated.", "AbortError"));
57
- controller = typeof AbortController !== "undefined" ? new AbortController() : {};
58
- const timeoutLength = toValue(opts.timeout);
59
- let timeoutId;
60
- if (timeoutLength) {
61
- timeoutId = setTimeout(() => controller.abort(new DOMException("Request aborted due to timeout.", "AbortError")), timeoutLength);
62
- controller.signal.onabort = () => clearTimeout(timeoutId);
63
- }
56
+ const asyncData = useAsyncData(watchSources === false ? key.value : key, (_, { signal }) => {
64
57
  let _$fetch = opts.$fetch || globalThis.$fetch;
65
58
  if (import.meta.server && !opts.$fetch) {
66
59
  const isLocalFetch = typeof _request.value === "string" && _request.value[0] === "/" && (!toValue(opts.baseURL) || toValue(opts.baseURL)[0] === "/");
@@ -68,9 +61,7 @@ export function useFetch(request, arg1, arg2) {
68
61
  _$fetch = useRequestFetch();
69
62
  }
70
63
  }
71
- return _$fetch(_request.value, { signal: controller.signal, ..._fetchOptions }).finally(() => {
72
- clearTimeout(timeoutId);
73
- });
64
+ return _$fetch(_request.value, { signal, ..._fetchOptions });
74
65
  }, _asyncDataOptions);
75
66
  return asyncData;
76
67
  }
@@ -123,6 +123,8 @@ interface _NuxtApp {
123
123
  _execute: (opts?: AsyncDataExecuteOptions) => Promise<void>;
124
124
  /** @internal */
125
125
  _hash?: Record<string, string | undefined>;
126
+ /** @internal */
127
+ _abortController?: AbortController;
126
128
  } | undefined>;
127
129
  /** @internal */
128
130
  _loadingIndicator?: LoadingIndicator;
@@ -10,7 +10,7 @@ import { getQuery as getURLQuery, joinURL } from "ufo";
10
10
  import { propsToString, renderSSRHead } from "@unhead/vue/server";
11
11
  import destr from "destr";
12
12
  import { defineRenderHandler, getRouteRules, useNitroApp } from "nitropack/runtime";
13
- import { getEntryIds, getRenderer } from "../utils/renderer/build-files.js";
13
+ import { getRenderer } from "../utils/renderer/build-files.js";
14
14
  import { payloadCache } from "../utils/cache.js";
15
15
  import { renderPayloadJsonScript, renderPayloadResponse, renderPayloadScript, splitPayload } from "../utils/renderer/payload.js";
16
16
  import { createSSRContext, setSSRError } from "../utils/renderer/app.js";
@@ -18,6 +18,7 @@ import { renderInlineStyles } from "../utils/renderer/inline-styles.js";
18
18
  import { replaceIslandTeleports } from "../utils/renderer/islands.js";
19
19
  import { renderSSRHeadOptions } from "#internal/unhead.config.mjs";
20
20
  import { appHead, appTeleportAttrs, appTeleportTag, componentIslands, appManifest as isAppManifestEnabled } from "#internal/nuxt.config.mjs";
21
+ import entryIds from "#internal/nuxt/entry-ids.mjs";
21
22
  import { entryFileName } from "#internal/entry-chunk.mjs";
22
23
  import { buildAssetsURL, publicAssetsURL } from "#internal/nuxt/paths";
23
24
  import { relative } from "pathe";
@@ -77,7 +78,7 @@ export default defineRenderHandler(async (event) => {
77
78
  }
78
79
  }
79
80
  if (process.env.NUXT_INLINE_STYLES) {
80
- for (const id of await getEntryIds()) {
81
+ for (const id of entryIds) {
81
82
  ssrContext.modules.add(id);
82
83
  }
83
84
  }
@@ -20,4 +20,3 @@ export declare function getRenderer(ssrContext: NuxtSSRContext): Promise<{
20
20
  }>;
21
21
  }>;
22
22
  export declare const getSSRStyles: () => Promise<Record<string, () => Promise<string[]>>>;
23
- export declare const getEntryIds: () => Promise<string[]>;
@@ -10,21 +10,19 @@ const APP_ROOT_OPEN_TAG = `<${appRootTag}${propsToString(appRootAttrs)}>`;
10
10
  const APP_ROOT_CLOSE_TAG = `</${appRootTag}>`;
11
11
  const getServerEntry = () => import("#build/dist/server/server.mjs").then((r) => r.default || r);
12
12
  const getClientManifest = () => import("#build/dist/server/client.manifest.mjs").then((r) => r.default || r).then((r) => typeof r === "function" ? r() : r);
13
+ const getPrecomputedDependencies = () => import("#build/dist/server/client.precomputed.mjs").then((r) => r.default || r).then((r) => typeof r === "function" ? r() : r);
13
14
  export const getSSRRenderer = lazyCachedFunction(async () => {
14
- const manifest = await getClientManifest();
15
- if (!manifest) {
16
- throw new Error("client.manifest is not available");
17
- }
18
15
  const createSSRApp = await getServerEntry();
19
16
  if (!createSSRApp) {
20
17
  throw new Error("Server bundle is not available");
21
18
  }
22
- const options = {
23
- manifest,
19
+ const precomputed = import.meta.dev ? void 0 : await getPrecomputedDependencies();
20
+ const renderer = createRenderer(createSSRApp, {
21
+ precomputed,
22
+ manifest: import.meta.dev ? await getClientManifest() : void 0,
24
23
  renderToString,
25
24
  buildAssetsURL
26
- };
27
- const renderer = createRenderer(createSSRApp, options);
25
+ });
28
26
  async function renderToString(input, context) {
29
27
  const html = await _renderToString(input, context);
30
28
  if (import.meta.dev && process.env.NUXT_VITE_NODE_OPTIONS) {
@@ -35,7 +33,7 @@ export const getSSRRenderer = lazyCachedFunction(async () => {
35
33
  return renderer;
36
34
  });
37
35
  const getSPARenderer = lazyCachedFunction(async () => {
38
- const manifest = await getClientManifest();
36
+ const precomputed = import.meta.dev ? void 0 : await getPrecomputedDependencies();
39
37
  const spaTemplate = await import("#spa-template").then((r) => r.template).catch(() => "").then((r) => {
40
38
  if (spaLoadingTemplateOutside) {
41
39
  const APP_SPA_LOADER_OPEN_TAG = `<${appSpaLoaderTag}${propsToString(appSpaLoaderAttrs)}>`;
@@ -47,13 +45,13 @@ const getSPARenderer = lazyCachedFunction(async () => {
47
45
  return APP_ROOT_OPEN_TAG + r + APP_ROOT_CLOSE_TAG;
48
46
  }
49
47
  });
50
- const options = {
51
- manifest,
48
+ const renderer = createRenderer(() => () => {
49
+ }, {
50
+ precomputed,
51
+ manifest: import.meta.dev ? await getClientManifest() : void 0,
52
52
  renderToString: () => spaTemplate,
53
53
  buildAssetsURL
54
- };
55
- const renderer = createRenderer(() => () => {
56
- }, options);
54
+ });
57
55
  const result = await renderer.renderToString({});
58
56
  const renderToString = (ssrContext) => {
59
57
  const config = useRuntimeConfig(ssrContext.event);
@@ -86,12 +84,3 @@ export function getRenderer(ssrContext) {
86
84
  return process.env.NUXT_NO_SSR || ssrContext.noSSR ? getSPARenderer() : getSSRRenderer();
87
85
  }
88
86
  export const getSSRStyles = lazyCachedFunction(() => import("#build/dist/server/styles.mjs").then((r) => r.default || r));
89
- export const getEntryIds = () => getClientManifest().then((r) => {
90
- const entryIds = [];
91
- for (const entry of Object.values(r)) {
92
- if (entry._globalCSS) {
93
- entryIds.push(entry.src);
94
- }
95
- }
96
- return entryIds;
97
- });
package/dist/index.mjs CHANGED
@@ -3830,7 +3830,7 @@ function addDeclarationTemplates(ctx, options) {
3830
3830
  });
3831
3831
  }
3832
3832
 
3833
- const version = "4.2.0-29331207.25e91a2b";
3833
+ const version = "4.2.0-29331232.6f9cb0d2";
3834
3834
 
3835
3835
  const createImportProtectionPatterns = (nuxt, options) => {
3836
3836
  const patterns = [];
@@ -4206,7 +4206,8 @@ async function initNitro(nuxt) {
4206
4206
  "#internal/nuxt/app-config": () => nuxt.vfs["#build/app.config.mjs"]?.replace(/\/\*\* client \*\*\/[\s\S]*\/\*\* client-end \*\*\//, "") || "",
4207
4207
  "#spa-template": async () => `export const template = ${JSON.stringify(await spaLoadingTemplate(nuxt))}`,
4208
4208
  // this will be overridden in vite plugin
4209
- "#internal/entry-chunk.mjs": () => `export const entryFileName = undefined`
4209
+ "#internal/entry-chunk.mjs": () => `export const entryFileName = undefined`,
4210
+ "#internal/nuxt/entry-ids.mjs": () => `export default []`
4210
4211
  },
4211
4212
  routeRules: {
4212
4213
  "/__nuxt_error": { cache: false }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-nightly",
3
- "version": "4.2.0-29331207.25e91a2b",
3
+ "version": "4.2.0-29331232.6f9cb0d2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/nuxt/nuxt.git",
@@ -67,10 +67,10 @@
67
67
  "@nuxt/cli": "npm:@nuxt/cli-nightly@latest",
68
68
  "@nuxt/devalue": "^2.0.2",
69
69
  "@nuxt/devtools": "^2.6.5",
70
- "@nuxt/kit": "npm:@nuxt/kit-nightly@4.2.0-29331207.25e91a2b",
71
- "@nuxt/schema": "npm:@nuxt/schema-nightly@4.2.0-29331207.25e91a2b",
70
+ "@nuxt/kit": "npm:@nuxt/kit-nightly@4.2.0-29331232.6f9cb0d2",
71
+ "@nuxt/schema": "npm:@nuxt/schema-nightly@4.2.0-29331232.6f9cb0d2",
72
72
  "@nuxt/telemetry": "^2.6.6",
73
- "@nuxt/vite-builder": "npm:@nuxt/vite-builder-nightly@4.2.0-29331207.25e91a2b",
73
+ "@nuxt/vite-builder": "npm:@nuxt/vite-builder-nightly@4.2.0-29331232.6f9cb0d2",
74
74
  "@unhead/vue": "^2.0.14",
75
75
  "@vue/shared": "^3.5.22",
76
76
  "c12": "^3.3.0",
@@ -112,6 +112,7 @@
112
112
  "radix3": "^1.1.2",
113
113
  "scule": "^1.3.0",
114
114
  "semver": "^7.7.2",
115
+ "seroval": "^1.3.2",
115
116
  "std-env": "^3.9.0",
116
117
  "tinyglobby": "^0.2.15",
117
118
  "ufo": "^1.6.1",