Turbopack: add hmr test case and fix bugs (#53719)

### What?

test case for HMR

### Turbopack Changes

* https://github.com/vercel/turbo/pull/5686 <!-- Tobias Koppers - remove
error in update -->
This commit is contained in:
Tobias Koppers 2023-08-08 17:07:24 +02:00 committed by GitHub
parent d7405b0c28
commit 9d1b3f43a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 342 additions and 78 deletions

75
Cargo.lock generated
View file

@ -412,7 +412,7 @@ dependencies = [
[[package]]
name = "auto-hash-map"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"serde",
]
@ -3578,6 +3578,7 @@ dependencies = [
"serde",
"serde_json",
"shadow-rs",
"tokio",
"tracing",
"tracing-chrome",
"tracing-futures",
@ -3632,7 +3633,7 @@ dependencies = [
[[package]]
name = "node-file-trace"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"serde",
@ -7317,7 +7318,7 @@ dependencies = [
[[package]]
name = "turbo-tasks"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"async-trait",
@ -7349,7 +7350,7 @@ dependencies = [
[[package]]
name = "turbo-tasks-build"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"cargo-lock",
@ -7361,7 +7362,7 @@ dependencies = [
[[package]]
name = "turbo-tasks-bytes"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"bytes",
@ -7376,7 +7377,7 @@ dependencies = [
[[package]]
name = "turbo-tasks-env"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"dotenvs",
@ -7390,7 +7391,7 @@ dependencies = [
[[package]]
name = "turbo-tasks-fetch"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"indexmap 1.9.3",
@ -7407,7 +7408,7 @@ dependencies = [
[[package]]
name = "turbo-tasks-fs"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"auto-hash-map",
@ -7437,7 +7438,7 @@ dependencies = [
[[package]]
name = "turbo-tasks-hash"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"base16",
"hex",
@ -7449,7 +7450,7 @@ dependencies = [
[[package]]
name = "turbo-tasks-macros"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"convert_case 0.6.0",
@ -7463,7 +7464,7 @@ dependencies = [
[[package]]
name = "turbo-tasks-macros-shared"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"proc-macro2",
"quote",
@ -7473,7 +7474,7 @@ dependencies = [
[[package]]
name = "turbo-tasks-malloc"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"mimalloc",
]
@ -7481,7 +7482,7 @@ dependencies = [
[[package]]
name = "turbo-tasks-memory"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"auto-hash-map",
@ -7504,7 +7505,7 @@ dependencies = [
[[package]]
name = "turbo-tasks-testing"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"auto-hash-map",
@ -7517,7 +7518,7 @@ dependencies = [
[[package]]
name = "turbopack"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"async-recursion",
@ -7548,7 +7549,7 @@ dependencies = [
[[package]]
name = "turbopack-bench"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"chromiumoxide",
@ -7578,7 +7579,7 @@ dependencies = [
[[package]]
name = "turbopack-binding"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"auto-hash-map",
"mdxjs",
@ -7621,7 +7622,7 @@ dependencies = [
[[package]]
name = "turbopack-build"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"indexmap 1.9.3",
@ -7643,7 +7644,7 @@ dependencies = [
[[package]]
name = "turbopack-cli-utils"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"clap 4.1.11",
@ -7667,7 +7668,7 @@ dependencies = [
[[package]]
name = "turbopack-core"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"async-recursion",
@ -7696,7 +7697,7 @@ dependencies = [
[[package]]
name = "turbopack-create-test-app"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"clap 4.1.11",
@ -7709,7 +7710,7 @@ dependencies = [
[[package]]
name = "turbopack-css"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"async-trait",
@ -7731,7 +7732,7 @@ dependencies = [
[[package]]
name = "turbopack-dev"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"indexmap 1.9.3",
@ -7755,7 +7756,7 @@ dependencies = [
[[package]]
name = "turbopack-dev-server"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"async-compression",
@ -7792,7 +7793,7 @@ dependencies = [
[[package]]
name = "turbopack-ecmascript"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"async-trait",
@ -7826,7 +7827,7 @@ dependencies = [
[[package]]
name = "turbopack-ecmascript-hmr-protocol"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"serde",
"serde_json",
@ -7837,7 +7838,7 @@ dependencies = [
[[package]]
name = "turbopack-ecmascript-plugins"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"async-trait",
@ -7860,7 +7861,7 @@ dependencies = [
[[package]]
name = "turbopack-ecmascript-runtime"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"indoc",
@ -7877,7 +7878,7 @@ dependencies = [
[[package]]
name = "turbopack-env"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"indexmap 1.9.3",
@ -7893,7 +7894,7 @@ dependencies = [
[[package]]
name = "turbopack-image"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"base64 0.21.0",
@ -7913,7 +7914,7 @@ dependencies = [
[[package]]
name = "turbopack-json"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"serde",
@ -7928,7 +7929,7 @@ dependencies = [
[[package]]
name = "turbopack-mdx"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"mdxjs",
@ -7943,7 +7944,7 @@ dependencies = [
[[package]]
name = "turbopack-node"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"async-stream",
@ -7978,7 +7979,7 @@ dependencies = [
[[package]]
name = "turbopack-static"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"serde",
@ -7994,7 +7995,7 @@ dependencies = [
[[package]]
name = "turbopack-swc-utils"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"swc_core",
"turbo-tasks",
@ -8005,7 +8006,7 @@ dependencies = [
[[package]]
name = "turbopack-test-utils"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"once_cell",
@ -8023,7 +8024,7 @@ dependencies = [
[[package]]
name = "turbopack-wasm"
version = "0.1.0"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230807.2#f9cbcf26fe0416c1e1ee405dbc94906ad4846eaa"
source = "git+https://github.com/vercel/turbo.git?tag=turbopack-230808.2#59effa31de90fcb7f55034f29efcd939a5de70e9"
dependencies = [
"anyhow",
"indexmap 1.9.3",

View file

@ -44,11 +44,11 @@ swc_core = { version = "0.79.40" }
testing = { version = "0.33.21" }
# Turbo crates
turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230807.2" }
turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230808.2" }
# [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros..
turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230807.2" }
turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230808.2" }
# [TODO]: need to refactor embed_directory! macro usage in next-core
turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230807.2" }
turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-230808.2" }
# General Deps

View file

@ -51,6 +51,7 @@ once_cell = { workspace = true }
serde = "1"
serde_json = "1"
shadow-rs = { workspace = true }
tokio = { workspace = true, features = ["full"] }
tracing = { workspace = true }
tracing-futures = "0.2.5"
tracing-subscriber = { workspace = true }

View file

@ -1,7 +1,11 @@
use std::{path::PathBuf, sync::Arc};
use std::{path::PathBuf, sync::Arc, time::Duration};
use anyhow::{Context, Result};
use napi::{bindgen_prelude::External, JsFunction};
use anyhow::{anyhow, Context, Result};
use napi::{
bindgen_prelude::External,
threadsafe_function::{ThreadsafeFunction, ThreadsafeFunctionCallMode},
JsFunction, Status,
};
use next_api::{
project::{Middleware, ProjectContainer, ProjectOptions},
route::{Endpoint, Route},
@ -12,7 +16,7 @@ use next_core::tracing_presets::{
use tracing_subscriber::{
prelude::__tracing_subscriber_SubscriberExt, util::SubscriberInitExt, EnvFilter, Registry,
};
use turbo_tasks::{TransientInstance, TurboTasks, Vc};
use turbo_tasks::{TransientInstance, TurboTasks, UpdateInfo, Vc};
use turbopack_binding::{
turbo::tasks_memory::MemoryBackend,
turbopack::{
@ -304,7 +308,6 @@ pub fn project_entrypoints_subscribe(
let entrypoints = entrypoints.strongly_consistent().await?;
// TODO peek_issues and diagnostics
Ok((entrypoints, issues, diags))
},
move |ctx| {
@ -349,14 +352,12 @@ pub fn project_entrypoints_subscribe(
#[napi(ts_return_type = "{ __napiType: \"RootTask\" }")]
pub fn project_hmr_events(
#[napi(ts_arg_type = "{ __napiType: \"Project\" }")] project: External<
VcArc<Vc<ProjectContainer>>,
>,
#[napi(ts_arg_type = "{ __napiType: \"Project\" }")] project: External<ProjectInstance>,
identifier: String,
func: JsFunction,
) -> napi::Result<External<RootTask>> {
let turbo_tasks = project.turbo_tasks().clone();
let project = **project;
let turbo_tasks = project.turbo_tasks.clone();
let project = project.container;
let session = TransientInstance::new(());
subscribe(
turbo_tasks.clone(),
@ -422,3 +423,89 @@ pub fn project_hmr_events(
},
)
}
#[napi(object)]
struct HmrIdentifiers {
pub identifiers: Vec<String>,
}
#[napi(ts_return_type = "{ __napiType: \"RootTask\" }")]
pub fn project_hmr_identifiers_subscribe(
#[napi(ts_arg_type = "{ __napiType: \"Project\" }")] project: External<ProjectInstance>,
func: JsFunction,
) -> napi::Result<External<RootTask>> {
let turbo_tasks = project.turbo_tasks.clone();
let container = project.container;
subscribe(
turbo_tasks.clone(),
func,
move || async move {
let hmr_identifiers = container.hmr_identifiers();
let issues = get_issues(hmr_identifiers).await?;
let diags = get_diagnostics(hmr_identifiers).await?;
let hmr_identifiers = hmr_identifiers.strongly_consistent().await?;
Ok((hmr_identifiers, issues, diags))
},
move |ctx| {
let (hmr_identifiers, issues, diags) = ctx.value;
Ok(vec![TurbopackResult {
result: HmrIdentifiers {
identifiers: hmr_identifiers
.iter()
.map(|ident| ident.to_string())
.collect::<Vec<_>>(),
},
issues: issues
.iter()
.map(|issue| NapiIssue::from(&**issue))
.collect(),
diagnostics: diags.iter().map(|d| NapiDiagnostic::from(d)).collect(),
}])
},
)
}
#[napi(object)]
struct NapiUpdateInfo {
pub duration: u32,
pub tasks: u32,
}
impl From<UpdateInfo> for NapiUpdateInfo {
fn from(update_info: UpdateInfo) -> Self {
Self {
duration: update_info.duration.as_millis() as u32,
tasks: update_info.tasks as u32,
}
}
}
#[napi]
pub fn project_update_info_subscribe(
#[napi(ts_arg_type = "{ __napiType: \"Project\" }")] project: External<ProjectInstance>,
func: JsFunction,
) -> napi::Result<()> {
let func: ThreadsafeFunction<UpdateInfo> = func.create_threadsafe_function(0, |ctx| {
let update_info = ctx.value;
Ok(vec![NapiUpdateInfo::from(update_info)])
})?;
let turbo_tasks = project.turbo_tasks.clone();
tokio::spawn(async move {
loop {
let update_info = turbo_tasks
.get_or_wait_aggregated_update_info(Duration::from_secs(1))
.await;
let status = func.call(Ok(update_info), ThreadsafeFunctionCallMode::NonBlocking);
if !matches!(status, Status::Ok) {
let error = anyhow!("Error calling JS function: {}", status);
eprintln!("{}", error);
break;
}
}
});
Ok(())
}

View file

@ -24,7 +24,7 @@ once_cell = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
shadow-rs = { workspace = true }
tokio = { workspace = true, features = ["full"] }
tokio = { workspace = true }
turbopack-binding = { workspace = true, features = [
"__turbo_tasks_memory",
"__turbo_tasks_env",

View file

@ -125,10 +125,17 @@ impl ProjectContainer {
.cell())
}
/// See [Project::entrypoints].
#[turbo_tasks::function]
pub fn entrypoints(self: Vc<Self>) -> Vc<Entrypoints> {
self.project().entrypoints()
}
/// See [Project::hmr_identifiers].
#[turbo_tasks::function]
pub fn hmr_identifiers(self: Vc<Self>) -> Vc<Vec<String>> {
self.project().hmr_identifiers()
}
}
#[turbo_tasks::value]
@ -557,4 +564,14 @@ impl Project {
let from = from.get();
Ok(self.hmr_content(identifier).update(from))
}
/// Gets a list of all HMR identifiers that can be subscribed to. This is
/// only needed for testing purposes and isn't used in real apps.
#[turbo_tasks::function]
pub async fn hmr_identifiers(self: Vc<Self>) -> Result<Vc<Vec<String>>> {
Ok(self
.await?
.versioned_content_map
.keys_in_path(self.client_root()))
}
}

View file

@ -1,7 +1,7 @@
use std::collections::HashMap;
use anyhow::{bail, Result};
use turbo_tasks::{State, TryJoinIterExt, ValueDefault, ValueToString, Vc};
use turbo_tasks::{State, TryFlatJoinIterExt, TryJoinIterExt, ValueDefault, ValueToString, Vc};
use turbopack_binding::{
turbo::tasks_fs::FileSystemPath,
turbopack::core::{
@ -78,4 +78,19 @@ impl VersionedContentMap {
Vc::connect(content);
Ok(content)
}
#[turbo_tasks::function]
pub async fn keys_in_path(&self, root: Vc<FileSystemPath>) -> Result<Vc<Vec<String>>> {
let keys = {
let map = self.map.get();
map.keys().copied().collect::<Vec<_>>()
};
let root = &root.await?;
let keys = keys
.into_iter()
.map(|path| async move { Ok(root.get_path_to(&*path.await?).map(|p| p.to_string())) })
.try_flat_join()
.await?;
Ok(Vc::cell(keys))
}
}

View file

@ -10,8 +10,8 @@
"check": "tsc --noEmit"
},
"dependencies": {
"@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-230807.2",
"@vercel/turbopack-node": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-node/js?turbopack-230807.2",
"@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-230808.2",
"@vercel/turbopack-node": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-node/js?turbopack-230808.2",
"anser": "^2.1.1",
"css.escape": "^1.5.1",
"next": "*",

View file

@ -449,7 +449,11 @@ export interface Issue {
subIssues: Issue[]
}
export interface Diagnostics {}
export interface Diagnostics {
category: string
name: string
payload: unknown
}
export type TurbopackResult<T = {}> = T & {
issues: Issue[]
@ -474,10 +478,23 @@ export interface Update {
update: unknown
}
export interface HmrIdentifiers {
identifiers: string[]
}
export interface UpdateInfo {
duration: number
tasks: number
}
export interface Project {
update(options: ProjectOptions): Promise<void>
entrypointsSubscribe(): AsyncIterableIterator<TurbopackResult<Entrypoints>>
hmrEvents(identifier: string): AsyncIterableIterator<TurbopackResult<Update>>
hmrIdentifiersSubscribe(): AsyncIterableIterator<
TurbopackResult<HmrIdentifiers>
>
updateInfoSubscribe(): AsyncIterableIterator<TurbopackResult<UpdateInfo>>
}
export type Route =
@ -789,6 +806,24 @@ function bindingToApi(binding: any, _wasm: boolean) {
)
return subscription
}
hmrIdentifiersSubscribe() {
const subscription = subscribe<TurbopackResult<HmrIdentifiers>>(
false,
async (callback) =>
binding.projectHmrIdentifiersSubscribe(this._nativeProject, callback)
)
return subscription
}
updateInfoSubscribe() {
const subscription = subscribe<TurbopackResult<UpdateInfo>>(
true,
async (callback) =>
binding.projectUpdateInfoSubscribe(this._nativeProject, callback)
)
return subscription
}
}
class EndpointImpl implements Endpoint {

View file

@ -1419,11 +1419,11 @@ importers:
packages/next-swc/crates/next-core/js:
dependencies:
'@vercel/turbopack-ecmascript-runtime':
specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-230807.2
version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-230807.2(react-refresh@0.12.0)(webpack@5.86.0)'
specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-230808.2
version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-230808.2(react-refresh@0.12.0)(webpack@5.86.0)'
'@vercel/turbopack-node':
specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-node/js?turbopack-230807.2
version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-node/js?turbopack-230807.2'
specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-node/js?turbopack-230808.2
version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-node/js?turbopack-230808.2'
anser:
specifier: ^2.1.1
version: 2.1.1
@ -26413,9 +26413,9 @@ packages:
/zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
'@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-230807.2(react-refresh@0.12.0)(webpack@5.86.0)':
resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-230807.2}
id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-230807.2'
'@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-230808.2(react-refresh@0.12.0)(webpack@5.86.0)':
resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-230808.2}
id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-230808.2'
name: '@vercel/turbopack-ecmascript-runtime'
version: 0.0.0
dependencies:
@ -26426,8 +26426,8 @@ packages:
- webpack
dev: false
'@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-node/js?turbopack-230807.2':
resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-node/js?turbopack-230807.2}
'@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-node/js?turbopack-230808.2':
resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-node/js?turbopack-230808.2}
name: '@vercel/turbopack-node'
version: 0.0.0
dependencies:

View file

@ -711,6 +711,10 @@ exports[`next.rs api should allow to write pages edge page to disk: diagnostics
exports[`next.rs api should allow to write pages edge page to disk: issues 1`] = `Array []`;
exports[`next.rs api should allow to write root page to disk: diagnostics 1`] = `Array []`;
exports[`next.rs api should allow to write root page to disk: issues 1`] = `Array []`;
exports[`next.rs api should detect the correct routes: diagnostics 1`] = `
Array [
Object {
@ -720,6 +724,13 @@ Array [
"modularizeImports": "true",
},
},
Object {
"category": "NextFeatureTelemetry_category_tbd",
"name": "EVENT_BUILD_FEATURE_USAGE",
"payload": Object {
"platform-triplet": "true",
},
},
Object {
"category": "NextFeatureTelemetry_category_tbd",
"name": "EVENT_BUILD_FEATURE_USAGE",
@ -804,13 +815,6 @@ Array [
"turbotrace": "false",
},
},
Object {
"category": "NextFeatureTelemetry_category_tbd",
"name": "EVENT_BUILD_FEATURE_USAGE",
"payload": Object {
"x86_64-unknown-linux-gnu": "true",
},
},
]
`;

View file

@ -42,13 +42,49 @@ function normalizeIssues(issues: Issue[]) {
}
function normalizeDiagnostics(diagnostics: Diagnostics[]) {
return diagnostics.sort((a, b) => {
const a_ = JSON.stringify(a)
const b_ = JSON.stringify(b)
if (a_ < b_) return -1
if (a_ > b_) return 1
return 0
})
return diagnostics
.map((diagnostic) => {
if (diagnostic.name === 'EVENT_BUILD_FEATURE_USAGE') {
diagnostic.payload = Object.fromEntries(
Object.entries(diagnostic.payload).map(([key, value]) => {
return [
key.replace(
/^(x86_64|i686|aarch64)-(apple-darwin|unknown-linux-(gnu|musl)|pc-windows-msvc)$/g,
'platform-triplet'
),
value,
]
})
)
}
return diagnostic
})
.sort((a, b) => {
const a_ = JSON.stringify(a)
const b_ = JSON.stringify(b)
if (a_ < b_) return -1
if (a_ > b_) return 1
return 0
})
}
function raceIterators<T>(iterators: AsyncIterableIterator<T>[]) {
const nexts = iterators.map((iterator, i) =>
iterator.next().then((next) => ({ next, i }))
)
return (async function* () {
while (true) {
const remaining = nexts.filter((x) => x)
if (remaining.length === 0) return
const { next, i } = await Promise.race(remaining)
if (!next.done) {
yield next.value
nexts[i] = iterators[i].next().then((next) => ({ next, i }))
} else {
nexts[i] = undefined
}
}
})()
}
describe('next.rs api', () => {
@ -126,6 +162,13 @@ describe('next.rs api', () => {
})
const routes = [
{
name: 'root page',
path: '/',
type: 'page',
runtime: 'nodejs',
config: {},
},
{
name: 'pages edge api',
path: '/api/edge',
@ -253,4 +296,65 @@ describe('next.rs api', () => {
}
})
}
it('has hmr identifiers', async () => {
const result = await project.hmrIdentifiersSubscribe().next()
expect(result.done).toBe(false)
const identifiers = result.value.identifiers
expect(identifiers).toHaveProperty('length', expect.toBePositive())
const subscriptions = identifiers.map((identifier) =>
project.hmrEvents(identifier)
)
await Promise.all(
subscriptions.map(async (subscription) => {
const result = await subscription.next()
expect(result.done).toBe(false)
expect(result.value).toHaveProperty('resource', expect.toBeObject())
expect(result.value).toHaveProperty('type', 'issues')
expect(result.value).toHaveProperty('issues', expect.toBeEmpty())
expect(result.value).toHaveProperty('diagnostics', expect.toBeEmpty())
})
)
console.log('waiting for events')
let updateComplete = project.updateInfoSubscribe().next()
next.patchFile(
'pages/index.js',
'export default () => <div>hello world2</div>'
)
let foundUpdate = false
const result2 = await Promise.race([
(async () => {
const merged = raceIterators(subscriptions)
for await (const item of merged) {
if (item.type === 'partial') {
// there should only be a single partial update
expect(foundUpdate).toBe(false)
expect(item.instruction).toEqual({
type: 'ChunkListUpdate',
merged: [
expect.objectContaining({
chunks: expect.toBeObject(),
entries: expect.toBeObject(),
}),
],
})
expect(
Object.keys(item.instruction.merged[0].entries)
).toContainEqual(expect.stringContaining('/pages/index.js'))
foundUpdate = true
}
}
})(),
updateComplete,
new Promise((r) => setTimeout(() => r('timeout'), 30000)),
])
expect(result2).toMatchObject({
done: false,
value: {
duration: expect.toBePositive(),
tasks: expect.toBePositive(),
},
})
expect(foundUpdate).toBe(true)
})
})