Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 15 additions & 29 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ allsorts = { version = "0.14.0", default-features = false, features = [
] }
anyhow = "1.0.100"
async-trait = "0.1.64"
base64 = "0.22.1"
bincode = { version = "2.0.1", features = ["serde"] }
bitfield = "0.19.4"
bumpalo = { version = "3.19.0", features = ["boxed", "collections", "allocator-api2"] }
Expand Down Expand Up @@ -322,7 +323,7 @@ quote = "1.0.45"
rand = "0.10.1"
rayon = "1.10.0"
regex = "1.12.3"
regress = "0.10.4"
regress = "0.11.1"
reqwest = { version = "0.13.2", default-features = false }
ringmap = "0.2.5"
roaring = "0.11.4"
Expand Down
3 changes: 1 addition & 2 deletions crates/next-api/src/module_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,11 +300,10 @@ impl ServerActionsGraphs {
let result = self
.0
.iter()
.map(async |graph| {
.map(|graph| {
graph
.get_server_actions_for_endpoint(entry, rsc_asset_context)
.owned()
.await
})
.try_flat_join()
.await?;
Expand Down
1 change: 0 additions & 1 deletion crates/next-api/src/next_server_nft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,6 @@ impl Asset for ServerNftJsonAsset {
self.entries(),
Some(self.ignores()),
None,
hash_salt,
)
.await?
.iter()
Expand Down
64 changes: 41 additions & 23 deletions crates/next-api/src/nft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ pub async fn trace_endpoint(
.await?
.map(|v| *v),
Some(next_config.config_file_path(project_path.clone())),
hash_salt,
)
.await?;

Expand Down Expand Up @@ -284,12 +283,11 @@ pub async fn traced_modules_for_entries(
traced_entries: Vc<Modules>,
exclude_glob: Option<Vc<Glob>>,
forbidden_path: Option<Vc<FileSystemPath>>,
hash_salt: Vc<RcStr>,
) -> Result<Vc<Modules>> {
let exclude_glob_and_module_idents = if let Some(exclude_glob) = exclude_glob {
let exclude_glob = exclude_glob.await?;
let data = traced_module_data_for_graph(module_graph, traced_entries, hash_salt).await?;
Some((exclude_glob, data.idents.await?))
let idents = traced_module_idents_for_graph(module_graph, traced_entries).await?;
Some((exclude_glob, idents))
} else {
None
};
Expand Down Expand Up @@ -388,13 +386,12 @@ pub struct TracedModuleData {
pub hashes: ResolvedVc<TracedModuleDataHashes>,
}

/// This caches the paths for all modules in the graph so that we don't have to do it once per page.
/// This caches the paths for all modules in the graph without eagerly hashing their contents.
#[turbo_tasks::function]
pub async fn traced_module_data_for_graph(
async fn traced_module_idents_for_graph(
module_graph: Vc<ModuleGraph>,
traced_entries: Vc<Modules>,
hash_salt: Vc<RcStr>,
) -> Result<Vc<TracedModuleData>> {
) -> Result<Vc<TracedModuleDataIdents>> {
// This function is very similar to traced_modules_for_entries, but doesn't apply the glob and
// is executed only once for the whole graph.
let module_graph = module_graph.await?;
Expand Down Expand Up @@ -423,30 +420,51 @@ pub async fn traced_module_data_for_graph(
true,
)?;

let (idents, hashes): (FxHashMap<_, _>, FxHashMap<_, _>) = traced_modules
.into_iter()
Ok(Vc::cell(
traced_modules
.into_iter()
.map(async |module| Ok((module, module.ident().await?)))
.try_join()
.await?
.into_iter()
.collect(),
))
}

/// This caches the paths and content hashes for all modules in the graph so that we don't have to
/// compute them once per page.
#[turbo_tasks::function]
pub async fn traced_module_data_for_graph(
module_graph: Vc<ModuleGraph>,
traced_entries: Vc<Modules>,
hash_salt: Vc<RcStr>,
) -> Result<Vc<TracedModuleData>> {
let idents = traced_module_idents_for_graph(module_graph, traced_entries)
.to_resolved()
.await?;
let hashes = idents
.await?
.keys()
.copied()
.map(async |module| {
Ok((
(module, module.ident().await?),
(
module,
module
.source()
.await?
.context("NFT module has no content")?
.content()
.hash(hash_salt, HashAlgorithm::Xxh3Hash128Hex)
.await?,
),
module,
module
.source()
.await?
.context("NFT module has no content")?
.content()
.hash(hash_salt, HashAlgorithm::Xxh3Hash128Hex)
.await?,
))
})
.try_join()
.await?
.into_iter()
.unzip();
.collect();

Ok(TracedModuleData {
idents: ResolvedVc::cell(idents),
idents,
hashes: ResolvedVc::cell(hashes),
}
.cell())
Expand Down
8 changes: 2 additions & 6 deletions crates/next-api/src/versioned_content_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,12 +295,8 @@ impl VersionedContentMap {
};
let keys = keys
.into_iter()
.map(|path| {
let root = root.clone();
async move { Ok(root.get_path_to(&path).map(RcStr::from)) }
})
.try_flat_join()
.await?;
.filter_map(|path| root.get_path_to(&path).map(RcStr::from))
.collect();
Ok(Vc::cell(keys))
}

Expand Down
2 changes: 1 addition & 1 deletion crates/next-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ workspace = true
[dependencies]
anyhow = { workspace = true }
async-trait = { workspace = true }
base64 = "0.21.0"
base64 = { workspace = true }
allsorts = { workspace = true }
bincode = { workspace = true }
either = { workspace = true, features = ["serde"] }
Expand Down
6 changes: 1 addition & 5 deletions crates/next-core/src/emit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,7 @@ pub async fn emit_assets(
let first = iter.next().unwrap();
let ext: RcStr = path.extension().unwrap_or_default().into();
let conflicts = iter
.map(async |next| {
assets_diff(*next, *first, ext.clone(), node_root.clone())
.owned()
.await
})
.map(|next| assets_diff(*next, *first, ext.clone(), node_root.clone()).owned())
.try_flat_join()
.await?;
if let Some(detail) = conflicts.into_iter().next() {
Expand Down
5 changes: 2 additions & 3 deletions crates/next-core/src/next_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1883,12 +1883,11 @@ impl OutputFileTracingIncludesExcludes {
.iter()
.flat_map(|pattern| pattern.iter())
.filter_map(|pattern| pattern.as_str())
.map(async |pattern_str| {
.map(|pattern_str| {
let (glob, root) = relativize_glob(pattern_str, &project_path)?;
Ok((RcStr::from(glob), root))
})
.try_join()
.await?;
.collect::<Result<Vec<_>>>()?;
Ok((route_pattern, file_patterns))
})
.try_join()
Expand Down
2 changes: 1 addition & 1 deletion crates/next-custom-transforms/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ publish = false
workspace = true

[dependencies]
base64 = "0.21.0"
base64 = { workspace = true }
bytes-str = { workspace = true }
chrono = "0.4"
easy-error = "1.0.0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ Note that `'use cache: private'` does not use cache handlers and cannot be custo

## API Reference

A cache handler must implement the [`CacheHandler`](https://github.com/vercel/next.js/blob/canary/packages/next/src/server/lib/cache-handlers/types.ts) interface with the following methods:
A cache handler must implement the `CacheHandler` interface with the following methods. The `CacheHandler` and `CacheEntry` types are exported from `next/cache`:

```ts
import type { CacheHandler, CacheEntry } from 'next/cache'
```

### `get()`

Expand Down Expand Up @@ -227,7 +231,7 @@ const cacheHandler = {

## CacheEntry Type

The [`CacheEntry`](https://github.com/vercel/next.js/blob/canary/packages/next/src/server/lib/cache-handlers/types.ts) object has the following structure:
The `CacheEntry` object (exported from `next/cache`) has the following structure:

```ts
interface CacheEntry {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export interface NextAdapter {
onBuildComplete?: (ctx: {
routing: {
beforeMiddleware: Array<Route>
middlewareMatchers: Array<Route>
beforeFiles: Array<Route>
afterFiles: Array<Route>
dynamicRoutes: Array<Route>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Called after the build process completes with detailed information about routes

- `context.routing`: Object containing Next.js routing phases and metadata
- `routing.beforeMiddleware`: Routes executed before middleware (includes header and redirect handling)
- `routing.middlewareMatchers`: Middleware matcher definitions for this build, used to decide whether middleware should be invoked for a given request
- `routing.beforeFiles`: Rewrite routes checked before filesystem route matching
- `routing.afterFiles`: Rewrite routes checked after filesystem route matching
- `routing.dynamicRoutes`: Dynamic route matching table
Expand Down
Loading
Loading